How to Read Pega 7 BLOB (Storage Stream)

Pega uses a concept called Storage Stream (aka. Pega 7 BLOB) to store property data in a column in a pegaDATA database in compressed format. This column is named pzpvstream. The data type of this column is BLOB (binary large object) for most DB vendor software (e.g. Oracle, Microsoft SQL Server, PostgreSQL)). The Pega 7 BLOB column is used to store user-defined custom properties (and many other things). This allows the pegaDATA database to remain flexible when developers create custom properties and removes the need to change the DB schema.

However, this approach also causes the need for what Pega calls property optimization so that these custom properties can be used in reporting. For an example of property optimization and reporting, refer to:

This post shows two ways of reading from pzpvstream BLOBs by directly accessing the pegaDATA database:

  1. Using pegaDATA DB provided functions for reading single property values from a BLOB.
  2. Creating a Java/JDBC program to read the entire BLOB and decompress its contents.

For this example, the Pega 7.2.1 SSA Exercise System provided by Pega Academy was used. I ran it using Oracle VM VirtualBox on MacOS as described in the below post:

The Pega 7.2.1 SSA Exercise System uses the PostgreSQL 9.4 DB server. The pgAdmin tool is used in this example to access the pegaDATA database and to call functions and run queries as described in this post:

Summary

  1. Pega 7.2.1 SSA Exercise System DMSample Application
  2. Pega DB Functions for Reading Properties from Pega 7 BLOB
  3. Using Java/JDBC to Read Entire Pega 7 BLOB Objects

1  Pega 7.2.1 SSA Exercise System DMSample Application

A sample application is included in the Pega 7.2.1 SSA Exercise System distribution. It is called DMSample. Login to the Designer Studio with administrator@pega.com and install and open the application. Navigate to the Application Explorer and open the CreditLimitApplication case.

Pega7 Designer Studio - Edit Case Type View and Run Case Type

Run the case to create some case data in the pegaDATA database. For example, the case is run below and submitted for a customer named Brandon Thomas.

Pega7 Designer Studio - Run Case Type and Enter Customer Data

To view all instances of the CreditLimitApplication case type, right-click on it in the Application Explorer and select View > Instances.

Pega7 Designer Studio - Application Explorer - Menu to View Case Type Instances of CreditLimitApplication

Here, the case type instance with the ID A-3 was just inserted.

Pega7 Designer Studio - List of CreditLimitApplication Case Type Instances

The CreditLimitApplication case type belongs to a work class called DMOrg-DMSample-Work. Several properties are defined on this class. These properties are not optimized and thus stored inside the storage stream (BLOB) in the Pega 7 database.

Pega7 Designer Studio - Application Explorer - View Data Model and Properties of Work Class DMOrg-DMSample-Work

To find out to what database table the DMOrg-DMSample-Work class is mapped to, open the class definition and click on the Test Connection button.

Pega7 Designer Studio - View Class Definition of DMOrg-DMSample-Work and Test Connection to Pega 7 Database

The table name is shown in a new window. Here it is pegadata.pc_dms_work

Pega7 Designer Studio - View Class-to-Table Mapping of DMOrg-DMSample-Work Work Class

The Pega 7 database can be queried to retrieve the case type instances from that table using pgAdmin to execute SQL queries such as the example below.

SELECT
    pxcreatedatetime,
    pxcreateoperator,
    pxobjclass,
    pxinsname,
    pzinskey,
    pzpvstream 
FROM 
    pegadata.pc_work_dms;

The below screen shot shows the results of running the query in the pgAdmin tool.

PostgreSQL pgAdmin - Query Pega 7 Database Table pegadata.pc_work_dms

The last column, named pzpvstream, is the compressed Pega 7 BLOB. It contains the non-optimized custom properties’ values such as MinimumIncome and MaximumIncome that were entered on the Customer Information screen when the case was created. For general information on how PostgreSQL stores binary data in a byte array, see datatype-binary.

2  Pega DB Functions for Reading Properties from Pega 7 BLOB

The pega database schemas provide 3 functions to read properties from the storage stream:

  • pr_read_decimal_from_stream
  • pr_read_int_from_stream
  • pr_read_from_stream

Each function has 3 input parameters:

  • property – String, the name of the property to extract
  • inskey – String, the pzinskey value of the record to read from
  • storage_stream – Byte array, the actual storage stream to read from

For example: To read the MaximumIncome property form the case type instance were the pzinskey equals DMORG-DMSAMPLE-WORK A-3, a query with a sub-query as shown below needs to be executed. See lines 5 to 12, for how the Pega 7 BLOB is obtained in the sub-query and then passed into the function as the third parameter.

SELECT pegadata.pr_read_int_from_stream(
    'MaximumIncome',
    'DMORG-DMSAMPLE-WORK A-3',
    /* START: Get pzpvstream byte array */
    (
        SELECT
            pzpvstream 
        FROM 
            pegadata.pc_work_dms 
        WHERE 
            pzinskey = 'DMORG-DMSAMPLE-WORK A-3'
    )
    /* END: Get pzpvstream byte array */
)

This query returns the numeric MaximumIncome value for the given case type instance, which is 37,500.

PostgreSQL pgAdmin - Use Pega 7 PL/Java Function pr_read_int_from_stream to Read Custom Property in Pega 7 BLOB

3  Using Java/JDBC to Read Entire Pega 7 BLOB Objects

The SQL CREATE syntax of the function pr_read_from_stream can be viewed in pgAdmin and is shown below. In the function body, in lines 14 to 17, a static method of a Java class is called. The function input parameters are passed to that Java method, which inflates and decodes the Pega 7 BLOB.

-- FUNCTION: pegadata.pr_read_from_stream(character varying, character varying, bytea)

-- DROP FUNCTION pegadata.pr_read_from_stream(character varying, character varying, bytea);

CREATE OR REPLACE FUNCTION pegadata.pr_read_from_stream(
    property character varying,
    inskey character varying,
    storage_stream bytea)
RETURNS character varying
    LANGUAGE 'java'
    COST 100
    VOLATILE 
    ROWS 0
AS $BODY$
com.pega.pegarules.data.udf.directstreamreader.
    DirectStreamReaderPostgreSQL.get(java.lang.String, java.lang.String, byte[])
$BODY$;

ALTER FUNCTION pegadata.pr_read_from_stream(character varying, character varying, bytea)
    OWNER TO pega;

The class DirectStreamReaderPostgreSQL in the function body was created when a JAR file called prreadstream.jar was installed in the sqlj schema in the Pega DB as part of the Pega 7 installation. See PL/Java for more information on Java language support in PostgreSQL DB functions. The below query lists the installed JAR files. There are 2 and they are actually identical.

SELECT * FROM sqlj.jar_repository;
PostgreSQL pgAdmin - Query Pega 7 Database Table sqlj.jar_repository

The classes in this JAR file contain the logic to read and write to the Pega 7 BLOB. These classes are loaded into the sqlj schema and can be viewed using the query below:

SELECT * FROM sqlj.jar_entry WHERE jarid = 1;
PostgreSQL pgAdmin - Query Pega 7 Database Table sqlj.jar_entry to View PL/Java Classes for Accessing Pega 7 BLOB

There are 20 classes in the pegadataPRREDSTREAM in the JAR that was imported into the jar_entry table. These classes can be extracted so that an external Java program can use them to access the Pega 7 BLOB.

I setup a simple Java project in Eclipse to access the Pega 7 PostgreSQL database and to extract these classes. For details on how to setup a Java project in Eclipse Neon and add a user library for PostgreSQL JDBC support, see the below post:

Here is a screen shot of my Java project in Eclipse Neon. Note the PostgreSQL JDBC driver JAR in the PostgreSQL-JDBC user library. The source code of the 4 Java classes used to extract the Pega 7 PL/Java classes for BLOB access is shown below.

Eclipse Neon - Java Project Structure for Exporting Pega 7 PL/Java Classes for Accessing Pega 7 BLOB

The below Java class named PostgreSqlDAO is used to access the Pega 7 PostgresSql database.

  • The method getSqljClasses reads the Pega 7 PL/Java classes from the sqlj.jar_entry table.
  • The method getBlob is used to read a specified Pega 7 BLOB from the database.
package com.pegaxchange.blob;

import java.sql.*;
import java.util.*;

public class PostgreSqlDAO {

    private Connection conn;

    public void connect(String host, String port, String db, String user, String password) 
            throws SQLException {
        
        Properties p = new Properties();
        p.setProperty("user", user);
        p.setProperty("password", password);
        p.setProperty("ssl", "false");

        conn = DriverManager.getConnection("jdbc:postgresql://" + host + "/" + db, p);
    }

    public List<SqljClass> getSqljClasses(int jarId) throws SQLException {
        List<SqljClass> classes = new ArrayList<SqljClass>();

        PreparedStatement ps = conn.prepareStatement(
                "SELECT * FROM sqlj.jar_entry WHERE jarid = '" + jarId + "'");

        if (ps.execute()) {
            ResultSet rs = ps.getResultSet();

            while (rs.next()) { 
                classes.add(new SqljClass(
                    rs.getString("entryname"), rs.getBytes("entryimage")));
            }
        }

        return classes;
    }

    public byte[] getBlob(String schema, String table, String pzInsKey) throws SQLException {
        byte[] blob = null;

        PreparedStatement ps = conn.prepareStatement(
                "SELECT * FROM " + schema + "." + table + 
                    " WHERE pzinskey = '" + pzInsKey + "'");

        if (ps.execute()) {
            ResultSet rs = ps.getResultSet();
            rs.next();
            blob = rs.getBytes("pzpvstream");
        }

        return blob;
    }
}

The PostgreSql DAO class relies on a Java bean class named SqljClass for storing the jar_entry records obtained from the Pega 7 sqlj database. The source code is shown below. The Java byte code of the entryimage column is stored in the entryImage field of type byte array.

package com.pegaxchange.blob;

public class SqljClass {
    
    private String entryName;
    private byte[] entryImage;
    
    public SqljClass(String entryName, byte[] entryImage) {
        this.entryName = entryName;
        this.entryImage = entryImage;
    }
        
    public String getEntryName() {
        return entryName;
    }
        
    public byte[] getEntryImage() {
        return entryImage;
    }
}

The class ClassExporter whose source code is shown below does the following:

  1. It uses the PostgreSQL DAO class to load the JAR entries from the sqlj.jar_entry table.
  2. It writes the Java byte code from the entryimage columm to Java class files, using the entryname column values as the file names.
package com.pegaxchange.blob;

import java.io.*;
import java.sql.*;
import java.util.*;

public class ClassExporter {

    private PostgreSqlDAO dao;
    private List<SqljClass> sqljClasses;

    public ClassExporter() throws SQLException {
        dao = new PostgreSqlDAO();
        dao.connect("192.168.56.2", "5432", "pega", "user", "password");
    }
    
    public void createSqljClassFiles(int jarid) throws SQLException {
        // 
        // 1. Load JAR entries from the Pega 7 database (sqlj.jar_entry).
        //    "1" identifies "pegarulesPRREADSTREAM" in sqlj.jar_repository
        //
        sqljClasses = dao.getSqljClasses(1);
        
        // 2. Create class files based on class name and Java byte code.
        //
        final String folder = "/Users/username/pega7_sqlj_classes/";
        
        for (SqljClass c : sqljClasses) {
            
            File f = new File(folder + c.getEntryName());
            FileOutputStream fos = null;
            
            try {
                // create directory structure based on class package
                f.getParentFile().mkdirs();
                
                // create .class file
                f.createNewFile();
                
                // write Java byte code to .class file
                fos = new FileOutputStream(f);
                fos.write(c.getEntryImage(), 0, c.getEntryImage().length);

            } catch (Exception e) {
                e.printStackTrace();
            
            } finally {
                // clean up resources
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        ClassExporter app = new ClassExporter();
        app.createSqljClassFiles(1);
    }
}

Run the ClassExporter to extract all of the Pega 7 PL/Java classes that contain the logic to access the Pega 7 storage stream BLOB. The program will create the directories and Java class files in the specified location (see line 26) as shown below.

View Exported Pega 7 PL/Java Classes on File System

These classes can now be used in a Java program. I used Eclipse Neon to add these classes as an external source to my Java project. Right-click on the project and select Build Path > Configure Build Path. Then use the button Add External Class Folder and point to the folder to which the PL/Java classes were exported. The classes are now available in the Eclipse Java project under the References Library node.

Eclipse Neon - Referenced Libraries - Link External Source Folder to Use Pega 7 PL/Java Classes for Accessing Pega 7 BLOB

I also installed the Eclipse plug-in Enhanced Class Decompiler, which automatically decompiles Java class files into source code. The above image shows the source code of DirectStreamReaderPostgreSQL.class.

Eclipse Neon - Enhanced Class Decompiler Plugin for Viewing Source Code of Java .class Files

The exported Pega 7 PL/Java classes can now be used to perform a variety of BLOB operations. The below Java program simply prints the contents of the storage stream of the DMORG-DMSAMPLE-WORK A-3 instance from the pc_work_dms table that was shown earlier. See lines 28 through 30 for using InflaterV7 and DirectStreamV7.

package com.pegaxchange.blob;

import java.sql.SQLException;

import com.pega.pegarules.data.internal.clipboard.directstream.BadStreamDataException;
import com.pega.pegarules.data.internal.clipboard.directstream.DirectStreamEnvironmentAdapter;
import com.pega.pegarules.data.internal.clipboard.directstream.DirectStreamV7;
import com.pega.pegarules.data.internal.clipboard.directstream.InflaterV7;
import com.pega.pegarules.data.udf.directstreamreader.*;

public class PegaBlobReader extends ClassLoader {

    static final DirectStreamEnvironmentAdapter oEnvAdapter = new BasicEnvironmentAdapter();
    private PostgreSqlDAO dao;

    public PegaBlobReader() throws SQLException {
        dao = new PostgreSqlDAO();
        dao.connect("192.168.56.2", "5432", "pega", "username", "password");
    }
        
    public static void main(String[] args) throws SQLException {
        PegaBlobReader app = new PegaBlobReader();
        byte[] pzpvstream = app.dao.getBlob(
                              "pegadata", "pc_work_dms", "DMORG-DMSAMPLE-WORK A-3");
        byte[] directStreamBytes;
        
        try {
            directStreamBytes = InflaterV7.inflateV7(pzpvstream, oEnvAdapter);
            DirectStreamV7 dsv7 = new DirectStreamV7(
                               directStreamBytes, directStreamBytes.length, oEnvAdapter);
            
            System.out.println(dsv7.toString());
            System.out.println(dsv7.dump());
            
        } catch (BadStreamDataException e) {
            e.printStackTrace();
        }
    }
}

The method DirectStreamV7.toString() creates the below String representation of the given Pega 7 BLOB. The non-optimized properties are highlighted in green.

.MaximumAge (@Z:sNN:) 30
.pxCoveredInsKeys (@Z:lTY:) <empty list>
.pyOrigUserID (@Z:sTN:) Administrator@pega.com
.pyTemporaryObject (@Z:sSN:) false
.pxCoveredCountOpen (@Z:sNY:) 0
.pyCaseFilterDescription (@Z:sTN:) Current Assignments and Subcases
.pyShowCompletedAssignments (@Z:sSN:) false
.pxCoveredCountUnsatisfied (@Z:sNY:) 0
.pxSystemUpdateDetailsList (@Z:L*YEmbed-CaseUpdate:)<empty PageList>
.pyStatusWork (@Z:sTN32:) Resolved-Accepted
.pyResolvedTime (@Z:sRN:) 440.0
.pxFlow (@Z:G*YEmbed-PegaEPRO-FlowPage:)
 -->.pzInternalCaseFlow (@Z:S*YEmbed-PegaEPRO-FlowPage:)
 --> -->.pxIsInvestigative (@Z:sSY:) false
 --> -->.pyFirstRun (@Z:sSN:) false
 --> -->.pyFlowParameters (@Z:S*N:)
 --> --> -->.ReferencePageName (@Z:s?N:) pyWorkPage
 --> --> -->.isNewCase (@Z:s?N:) true
 --> --> -->.flowName (@Z:s?N:) pzInternalCaseFlow
 --> --> -->.AssignTo (@Z:s?N:) default@pega.com
 --> -->.pyFlowCalledCount (@Z:sNN:) 1
 --> -->.pxAssignIsVirtual (@Z:sSY:) true
 --> -->.pyLastFlowStep (@Z:sTN:) ASSIGNMENT63
 --> -->.pyLastFlowStepLabel (@Z:sTN:) Perform action
 --> -->.pxTimeFlowStarted (@Z:sTY:) 20180215T093420.463 GMT
 --> -->.pxFlowInsKey (@Z:sTY:) RULE-OBJ-FLOW WORK- 
               PZINTERNALCASEFLOW #20151105T160214.591 GMT
 --> -->.pyDraftMode (@Z:sSN:) false
 --> -->.pyDeferCommit (@Z:sSN:) false
 --> -->.pxRouteTo (@Z:sTY:) default@pega.com
 --> -->.pxSubscript (@Z:s?N:) pzInternalCaseFlow
 --> -->.pxAssignActivity (@Z:sTY:) pzCreateInternalAssignment
 --> -->.pyFlowPath (@Z:L!NEmbed-PegaEPRO-FlowPath:)
 --> --> -->.pyStepLabel (@Z:sTN:) Perform action
 --> --> -->.pyFAProcessOnJump (@Z:sSN:) false
 --> --> -->.pxObjClass (@Z:s?N:) Embed-PegaEPRO-FlowPath
 --> --> -->.pyFlowStep (@Z:sTN:) ASSIGNMENT63
 --> --> -->.pyDisplay (@Z:sSN:) false
 --> --> -->.pyStepType (@Z:sTN:) ASSIGNMENT
 --> -->.pyContexts (@Z:G*NEmbed-PegaEPRO-FlowContext:)<empty Page>
 --> -->.pxAssignClass (@Z:sTY:) Assign-Internal
 --> -->.pyDeferErrors (@Z:sSN:) false
 --> -->.pxLastUpdateBy (@Z:sTY:) Administrator@pega.com
 --> -->.pxAssignmentKey (@Z:sTY:) 
               ASSIGN-INTERNAL DMORG-DMSAMPLE-WORK A-3!PZINTERNALCASEFLOW
 --> -->.pxSystemFlow (@Z:sSY:) true
 --> -->.pyCategory (@Z:sTN:) FlowStandard
 --> -->.pyFlowType (@Z:sTN:) pzInternalCaseFlow
 --> -->.pxObjClass (@Z:s?N:) Embed-PegaEPRO-FlowPage
 --> -->.pyFlowInterestPageClass (@Z:sTN:) DMOrg-DMSample-Work-CreditLimitApplication
.pyOwnerDivision (@Z:sTN32:) Administration
.pyStatusCustomerSat (@Z:stN32:) New
.pyNextEmailThreadID (@Z:sNN:) 1
.pxCreateOpName (@Z:sTY:) Administrator
.LoadingCustomerData (@Z:sSN:) false
.MaximumIncome (@Z:sNN:) 37500
.pxCurrentStageSubscript (@Z:sTY:) PRIM2_2
.pyInternalAssignmentHandle (@Z:sTN:) 
 ASSIGN-INTERNAL DMORG-DMSAMPLE-WORK A-3!PZINTERNALCASEFLOW
.pyOrigUserWorkgroup (@Z:sTN64:) Default
.MinimumIncome (@Z:sNN:) 20000
.pxApplication (@Z:sTY:) DMSample
.pyWorkPartiesRule (@Z:sTN:) pyCaseManagementDefault
.pxCurrentStageLabel (@Z:sTY:) Recommendation
.pyShowCases (@Z:sSN:) true
.pyElapsedStatusOpen (@Z:sRN:) 0
.pyElapsedStatusNew (@Z:sRN:) 440.0
.pxUpdateCounter (@Z:sNY:) 5
.pyOrigDivision (@Z:sTN32:) Administration
.pxUrgencyWork (@Z:sRY:) 10
.pyConfirmationNote (@Z:sTN:) Thank you for your input
.pyStatusWorkOld (@Z:sTN32:) Resolved-Accepted
.pzIndexCount (@Z:sNY:) 1
.UnlimitedSMS (@Z:sTN:) false
.pzInsKey (@Z:sIY:) DMORG-DMSAMPLE-WORK A-3
.pxCoveredCount (@Z:sNY:) 0
.pxUrgencyPartyTotal (@Z:sRY:) 0
.pyFolderType (@Z:sIN32:) pyDefault
.pyPushNotificationsEnabled (@Z:sSN:) false
.pyFlowName (@Z:sTN64:) pyStartCase
.pyStatusWorkTimestamp (@Z:sMN:) 20180215T094141.342 GMT
.pxInsName (@Z:sIY:) A-3
.pyOwnerOrg (@Z:sTN32:) pega.com
.pxUpdateOperator (@Z:sTY:) Administrator@pega.com
.pyAgeFromDate (@Z:sMN:) 20180215T093420.451 GMT
.pyFlowKey (@Z:sTN:) 
 RULE-OBJ-FLOW DMORG-DMSAMPLE-WORK-CREDITLIMITAPPLICATION PYSTARTCASE #20150114T150632.196 GMT
.pyElapsedCustomerUnsatisfied (@Z:sRN:) 0.0
.pxUrgencyWorkClass (@Z:sRY:) 10
.pyOwnerOrgUnit (@Z:sTN32:) Installation
.pyLabel (@Z:sTN64:) Credit Limit Application
.pyWorkParty (@Z:G*IData-Party:)
 -->.Owner (@Z:S*IData-Party:)
 --> -->.pxSubscript (@Z:s?N:) Owner
 --> -->.pxPartyRole (@Z:sIN:) Owner
 --> -->.pyPartyClassPrompt (@Z:sTN:) Case Owner
 --> -->.pyFullName (@Z:sTN:) Administrator
 --> -->.pyFirstName (@Z:sTN:) Administrator
 --> -->.pyUserIdentifier (@Z:sTN:) Administrator@pega.com
 --> -->.pyCorrPreferences (@Z:lTN:) Email
 --> -->.pyPartyRoleVisibleOnEntry (@Z:sSN:) true
 --> -->.pyAddresses (@Z:G*NData-Address:)
 --> --> -->.Email (@Z:S*NData-Address:)
 --> --> --> -->.pxObjClass (@Z:sIY:) Data-Address-Email
 --> --> --> -->.pyEmailAddress (@Z:sTN:) Administrator@pega.com
 --> --> --> -->.pxSubscript (@Z:s?N:) Email
 --> -->.pyPartyLabel (@Z:sTN:) Owner
 --> -->.pyLabel (@Z:sTN64:)  Administrator
 --> -->.pyPartyNotified (@Z:sSN:) false
 --> -->.pyWorkPartyUri (@Z:sTN:) Administrator@pega.com
 --> -->.pyEmail1 (@Z:sTN:) Administrator@pega.com
 --> -->.pzIndexes (@Z:gNY:)
 --> --> -->.PartyURI (@Z:sNY:) 0
 --> -->.pyUserName (@Z:sTN:) Administrator
 --> -->.pxObjClass (@Z:s?N:) Data-Party-Operator
 --> -->.pzIndexOwnerKey (@Z:sTN:) DMORG-DMSAMPLE-WORK A-3
.MinimumAge (@Z:sNN:) 18
.FourG (@Z:sTN:) false
.pxCreateDateTime (@Z:sMY:) 20180215T093420.451 GMT
.pxSaveDateTime (@Z:sMY:) 20180215T094141.341 GMT
.pyShowOpenAssignments (@Z:sSN:) true
.pyWorkIDPrefix (@Z:sTN:) A-
.International (@Z:sTN:) false
.pyNotifyQuickStream (@Z:sTN:) QuestionAboutItem
.pyID (@Z:sTN32:) A-3
.pyLabelOld (@Z:sTN:) Credit Limit Application
.pxCurrentStage (@Z:sTY:) PRIM2
.pxUpdateOpName (@Z:sTY:) Administrator
.pySatisfactionChangeTimestamp (@Z:sMN:) 20180215T093420.476 GMT
.pyOrigUserDivision (@Z:sTN32:) Administration
.pyOwnerUserID (@Z:sTN:) Administrator@pega.com
.pyAttachmentCategories (@Z:lTN:) <empty list>
.pxUpdateOrgUnit (@Z:sTY32:) Installation
.pxUpdateSystemID (@Z:sTY:) pega
.pyOrigOrg (@Z:sTN32:) pega.com
.pxUpdateDateTime (@Z:sMY:) 20180215T094141.341 GMT
.pyElapsedStatusPending (@Z:sRN:) 0
.pyOrigOrgUnit (@Z:sTN32:) Installation
.pxObjClass (@Z:sIY:) DMOrg-DMSample-Work-CreditLimitApplication
.pxStageHistory (@Z:L*YEmbed-StageHistory:)
 -->.pxStageName (@Z:sTY:) Call Context
 -->.pxSubscript (@Z:sIY:) PRIM1_1
 -->.pxProcesses (@Z:L*YEmbed-StageProcessHistory:)
 --> -->.pxIsOptional (@Z:sSY:) false
 --> -->.pxSubscript (@Z:sIY:) CallContext
 --> -->.pxSteps (@Z:L*YEmbed-StageStepHistory:)
 --> --> -->.pxObjClass (@Z:s?N:) Embed-StageStepHistory
 --> --> -->.pxStepType (@Z:sTY:) ASSIGNMENT
 --> --> -->.pyLabel (@Z:sTN64:) Increase Credit Limit
 --> --> -->.pxStepID (@Z:sTY:) ASSIGNMENT63
 --> -->.pxFlowID (@Z:sTY:) FLOW2
 --> -->.pxObjClass (@Z:sIY:) Embed-StageProcessHistory
 --> -->.pxStartedBy (@Z:sTY:) Administrator
 --> -->.pxCompletedTime (@Z:sMY:) 20180215T094137.808 GMT
 --> -->.pxCompletedBy (@Z:sTY:) Administrator
 --> -->.pxIsComplete (@Z:sTY:) True
 --> -->.pyLabel (@Z:sTN64:) Call Context
 --> -->.pxProcessName (@Z:sTY:) CallContext
 --> -->.pxStartTime (@Z:sMY:) 20180215T093420.467 GMT
 -->.pxCompletedStageTime (@Z:sMY:) 20180215T094137.809 GMT
 -->.pxStageID (@Z:sTY:) PRIM1
 -->.pxObjClass (@Z:sIY:) Embed-StageHistory
 -->.pxCompletedBy (@Z:sTY:) Administrator
 -->.pxStageType (@Z:sTY:) Primary
 -->.pxWentTo (@Z:sTY:) PRIM2
 -->.pxEnterStageTime (@Z:sMY:) 20180215T093420.467 GMT
 -->.pxStageName (@Z:sTY:) Recommendation
 -->.pxSubscript (@Z:sIY:) PRIM2_2
 -->.pxProcesses (@Z:L*YEmbed-StageProcessHistory:)
 --> -->.pxIsOptional (@Z:sSY:) false
 --> -->.pxSubscript (@Z:sIY:) Recommendation
 --> -->.pxSteps (@Z:L*YEmbed-StageStepHistory:)
 --> --> -->.pxObjClass (@Z:s?N:) Embed-StageStepHistory
 --> --> -->.pxStepType (@Z:sTY:) DECISION
 --> --> -->.pyLabel (@Z:sTN64:) Credit Application
 --> --> -->.pxStepID (@Z:sTY:) Decision1
 --> --> -->.pxObjClass (@Z:s?N:) Embed-StageStepHistory
 --> --> -->.pxStepType (@Z:sTY:) ASSIGNMENT
 --> --> -->.pyLabel (@Z:sTN64:) Accept Application
 --> --> -->.pxStepID (@Z:sTY:) Assignment1
 --> -->.pxFlowID (@Z:sTY:) FLOW0
 --> -->.pxObjClass (@Z:sIY:) Embed-StageProcessHistory
 --> -->.pxStartedBy (@Z:sTY:) Administrator
 --> -->.pxCompletedTime (@Z:sMY:) 20180215T094141.340 GMT
 --> -->.pxCompletedBy (@Z:sTY:) Administrator
 --> -->.pxIsComplete (@Z:sTY:) True
 --> -->.pyLabel (@Z:sTN64:) Recommendation
 --> -->.pxProcessName (@Z:sTY:) Recommendation
 --> -->.pxStartTime (@Z:sMY:) 20180215T094137.811 GMT
 -->.pxStageID (@Z:sTY:) PRIM2
 -->.pxObjClass (@Z:sIY:) Embed-StageHistory
 -->.pxCameFrom (@Z:sTY:) PRIM1
 -->.pxStageType (@Z:sTY:) Primary
 -->.pxEnterStageTime (@Z:sMY:) 20180215T094137.809 GMT
.pxLockHandle (@Z:sTY:) DMORG-DMSAMPLE-WORK A-3
.pxCreateSystemID (@Z:sTY:) pega
.pxCreateOperator (@Z:sTY:) Administrator@pega.com

The method DirectStreamV7.dump() creates a more verbose String representation of the Pega 7 BLOB:

Total stream size: 14856  Bytes in use: 14856

Section Table
  Page section offset: 33
  String section offset: 3504
  Page List section offset: 13316
  Messages section offset: 13404
  Hash section offset: 13412

Page Section
  Section length: 3471
  Has Reference: N
  Has Transient: N
  Offsets relative to: 110
    
Num page indexes: 17
    0) 0
    1) 1282
    2) 1316
    3) 1622
    4) 1656
    5) 1722
    6) 1756
    7) 1934
    8) 2144
    9) 2226
    10) 2372
    11) 2582
    12) 2664
    13) 2746
    14) 2780
    15) 3198
    16) 3280

  Page at index 0, offset: 0
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                          Num entries: 79 Hash table offset - 0
    Bucket index  PropertyEntry Offset
    0 0
    1 2
    4 3
    5 4
    6 5
    10  6
    12  8
    13  9
    14  11
    15  12
    21  13
    24  15
    26  16
    27  17
    28  19
    36  22
    37  24
    38  25
    40  28
    43  31
    47  32
    49  33
    50  35
    53  36
    54  37
    59  38
    61  39
    62  41
    64  42
    66  44
    67  45
    69  46
    71  47
    78  48
    79  51
    83  52
    84  54
    90  55
    91  57
    94  58
    97  59
    101 61
    102 62
    103 64
    104 66
    106 67
    107 68
    109 69
    114 71
    120 73
    121 74
    122 76
    123 77
    126 78

    Hash  Offset  Name Index  Name  Value Attr
    -861670689  128 4080  MaximumAge  4108  2564
    1411453876  144 8088  pxCoveredInsKeys  -1  8128
    -1  160 2902  pyOrigUserID  1000  738
    -1  176 2586  pyTemporaryObject 1592  400
    -1  192 8480  pxCoveredCountOpen  468 1926
    -1  208 8150  pyCaseFilterDescription 8204  738
    -156283455  224 3734  pyShowCompletedAssignments  1592  400
    -821956424  240 8742  pxCoveredCountUnsatisfied 468 1926
    -1  256 9198  pxSystemUpdateDetailsList -1  9256
    1131181324  272 3546  pyStatusWork  2972  2792
    -1344117874 288 3698  pyResolvedTime  3182  3060
    -1  304 6014  pxFlow  13  7930
    -1  320 9160  pyOwnerDivision 3662  2792
    365297869 336 268 pyStatusCustomerSat 314 328
    40910117  352 3490  pyNextEmailThreadID 3536  2564
    -1  368 9768  pxCreateOpName  930 56
    -1  384 4034  LoadingCustomerData 1592  400
    1223580617  400 2512  MaximumIncome 2546  2564
    1527550558  416 3414  pxCurrentStageSubscript 3468  56
    -1689539749 432 554 pyInternalAssignmentHandle  614 738
    -600239431  448 4120  pyOrigUserWorkgroup 4166  2086
    -1249080521 464 8800  MinimumIncome 8834  2564
    -1264186840 480 7998  pxApplication 8032  56
    1671980550  496 8646  pyWorkPartiesRule 8688  738
    -1  512 3794  pxCurrentStageLabel 3840  56
    -1624161731 528 354 pyShowCases 384 400
    -2065921809 544 3014  pyElapsedStatusOpen 468 3060
    1595924059  560 3138  pyElapsedStatusNew  3182  3060
    1065426891  576 3268  pxUpdateCounter 3306  1926
    769625783 592 3626  pyOrigDivision  3662  2792
    994772690 608 8276  pxUrgencyWork 2404  478
    -1  624 2220  pyConfirmationNote  2264  738
    -1  640 2934  pyStatusWorkOld 2972  2792
    -192720633  656 4188  pzIndexCount  3536  1926
    541885656 672 8056  UnlimitedSMS  1592  738
    -1  688 2628  pzInsKey  1750  1224
    -1  704 9310  pxCoveredCount  468 1926
    -1  720 422 pxUrgencyPartyTotal 468 478
    -1  736 9464  pyFolderType  9496  9522
    -1212157284 752 2416  pyPushNotificationsEnabled  1592  400
    1900610050  768 3316  pyFlowName  3344  2086
    -1  784 8310  pyStatusWorkTimestamp 8360  3116
    1733496945  800 2320  pxInsName 2346  1224
    1534442586  816 2740  pyOwnerOrg  2768  2792
    -1  832 3374  pxUpdateOperator  1000  56
    -1  848 3082  pyAgeFromDate 800 3116
    -1  864 9548  pyFlowKey 9574  738
    -1  880 5936  pyElapsedCustomerUnsatisfied  6000  3060
    -1025169978 896 2360  pxUrgencyWorkClass  2404  478
    -145470210  912 8558  pyOwnerOrgUnit  8448  2792
    -141500821  928 2028  pyLabel 2846  2086
    -1  944 854 pyWorkParty 1 2178
    1610328625  960 9022  MinimumAge  9050  2564
    68069313  976 9126  FourG 1592  738
    -1  992 760 pxCreateDateTime  800 246
    256056928 1008  2476  pxSaveDateTime  192 246
    466897174 1024  8852  pyShowOpenAssignments 384 400
    -1  1040  3578  pyWorkIDPrefix  3614  738
    -1  1056  9346  International 1592  738
    -1164494405 1072  2652  pyNotifyQuickStream 2698  738
    3455204 1088  9144  pyID  2346  2792
    -1  1104  2818  pyLabelOld  2846  738
    -14471379 1120  500 pxCurrentStage  536 56
    1763140701  1136  3232  pxUpdateOpName  930 56
    664515921 1152  8902  pySatisfactionChangeTimestamp 8968  3116
    1279774370  1168  9380  pyOrigUserDivision  3662  2792
    -1  1184  8524  pyOwnerUserID 1000  738
    -1  1200  78  pyAttachmentCategories  -1  130
    -1  1216  9062  pxUpdateOrgUnit 8448  9100
    1016601499  1232  0 pxUpdateSystemID  40  56
    317403802 1248  3968  pyOrigOrg 2768  2792
    833265580 1264  152 pxUpdateDateTime  192 246
    1585440978  1280  8594  pyElapsedStatusPending  468 3060
    -1  1296  8414  pyOrigOrgUnit 8448  2792
    1738111209  1312  1152  pxObjClass  3876  1224
    1649972702  1328  4220  pxStageHistory  0 5878
    -1  1344  3200  pxLockHandle  1750  56
    -1  1360  3994  pxCreateSystemID  40  56
    -1  1376  9424  pxCreateOperator  1000  56

  Page at index 1, offset: 1282
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1 
                                          Num entries: 1 Hash table offset - 516
    Bucket index  PropertyEntry Offset
    1 0

    Hash  Offset  Name Index  Name  Value Attr
    -1  1410  884 Owner 2 2136

  Page at index 2, offset: 1316
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                          Num entries: 18 Hash table offset - 528
    Bucket index  PropertyEntry Offset
    1 0
    2 1
    6 3
    8 4
    9 5
    11  6
    12  7
    13  8
    14  10
    15  11
    18  12
    19  13
    20  14
    22  15
    25  16
    31  17

    Hash  Offset  Name Index  Name  Value Attr
    -1  1444  1282  pxSubscript 884 1312
    -1283946668 1460  1052  pxPartyRole 884 1082
    642119263 1476  1804  pyPartyClassPrompt  1848  738
    -1  1492  902 pyFullName  930 738
    -1  1508  1650  pyFirstName 930 738
    -1  1524  1610  pyUserIdentifier  1000  738
    -1  1540  1500  pyCorrPreferences 1542  130
    -1  1556  1970  pyPartyRoleVisibleOnEntry 384 400
    1180125081  1572  1104  pyAddresses 3 1380
    1344407191  1588  1680  pyPartyLabel  884 738
    -1  1604  2028  pyLabel 2050  2086
    -1  1620  1554  pyPartyNotified 1592  400
    -1  1636  964 pyWorkPartyUri  1000  738
    -1  1652  2112  pyEmail1  1000  738
    -1  1668  1876  pzIndexes 5 1948
    -1  1684  1472  pyUserName  930 738
    -1  1700  1152  pxObjClass  1426  1312
    -1  1716  1712  pzIndexOwnerKey 1750  738

  Page at index 3, offset: 1622
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                          Num entries: 1 Hash table offset - 660
    Bucket index  PropertyEntry Offset
    0 0

    Hash  Offset  Name Index  Name  Value Attr
    -1  1750  1134  Email 4 1334

  Page at index 4, offset: 1656
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                          Num entries: 3 Hash table offset - 672
    Bucket index  PropertyEntry Offset
    1 0

    Hash  Offset  Name Index  Name  Value Attr
    1738111209  1784  1152  pxObjClass  1180  1224
    1458339169  1800  1246  pyEmailAddress  1000  738
    1016936931  1816  1282  pxSubscript 1134  1312

  Page at index 5, offset: 1722
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 1 Hash table offset - 692
    Bucket index  PropertyEntry Offset
    1 0

    Hash  Offset  Name Index  Name  Value Attr
    -1  1850  1902  PartyURI  468 1926

  Page at index 6, offset: 1756
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 10 Hash table offset - 704
    Bucket index  PropertyEntry Offset
    0 0
    1 1
    4 2
    6 3
    8 4
    9 5
    11  6
    14  9

    Hash  Offset  Name Index  Name  Value Attr
    -1  1884  4428  pxStageName 4458  56
    -1  1900  1282  pxSubscript 5408  1224
    -1  1916  4490  pxProcesses 1 5240
    -1  1932  5430  pxCompletedStageTime  5478  246
    -1  1948  5364  pxStageID 5390  56
    -1  1964  1152  pxObjClass  4256  1224
    1878957274  1980  4394  pxCompletedBy 930 56
    -1955958224 1996  5312  pxStageType 5342  56
    -660075817  2012  5532  pxWentTo  536 56
    -1  2028  4300  pxEnterStageTime  4340  246

  Page at index 7, offset: 1934
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 12 Hash table offset - 772
    Bucket index  PropertyEntry Offset
    0 0
    1 1
    5 2
    9 4
    10  6
    11  7
    14  8
    15  10

    Hash  Offset  Name Index  Name  Value Attr
    -1  2062  5186  pxIsOptional  1592  5218
    -1  2078  1282  pxSubscript 4752  1224
    -163096065  2094  4812  pxSteps 2 5048
    -1140274447 2110  5114  pxFlowID  5138  56
    1738111209  2126  1152  pxObjClass  4520  1224
    -1626699888 2142  5156  pxStartedBy 930 56
    -1  2158  4626  pxCompletedTime 4664  246
    -1  2174  4394  pxCompletedBy 930 56
    1287313579  2190  4578  pxIsComplete  4610  56
    -141500821  2206  2028  pyLabel 4458  2086
    1678852722  2222  4718  pxProcessName 4752  56
    -1627200217 2238  4782  pxStartTime 4340  246

  Page at index 8, offset: 2144
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 4 Hash table offset - 840
    Bucket index  PropertyEntry Offset
    1 0
    2 1
    6 2

    Hash  Offset  Name Index  Name  Value Attr
    -1  2272  1152  pxObjClass  4834  1312
    -1  2288  4886  pxStepType  4914  56
    -141500821  2304  2028  pyLabel 4942  2086
    -761011953  2320  4992  pxStepID  5016  56

  Page at index 9, offset: 2226
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 8 Hash table offset - 876
    Bucket index  PropertyEntry Offset
    0 0
    1 1
    4 2
    8 3
    9 4
    10  5
    11  6
    14  7

    Hash  Offset  Name Index  Name  Value Attr
    -1  2354  4428  pxStageName 3840  56
    -1  2370  1282  pxSubscript 3468  1224
    -1  2386  4490  pxProcesses 3 5240
    -1  2402  5364  pxStageID 536 56
    -1  2418  1152  pxObjClass  4256  1224
    -1  2434  5556  pxCameFrom  5390  56
    -1  2450  5312  pxStageType 5342  56
    -1  2466  4300  pxEnterStageTime  5478  246

  Page at index 10, offset: 2372
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 12 Hash table offset - 944
    Bucket index  PropertyEntry Offset
    0 0
    1 1
    5 2
    9 4
    10  6
    11  7
    14  8
    15  10

    Hash  Offset  Name Index  Name  Value Attr
    -1  2500  5186  pxIsOptional  1592  5218
    -1  2516  1282  pxSubscript 3840  1224
    -163096065  2532  4812  pxSteps 4 5048
    -1140274447 2548  5114  pxFlowID  5860  56
    1738111209  2564  1152  pxObjClass  4520  1224
    -1626699888 2580  5156  pxStartedBy 930 56
    -1  2596  4626  pxCompletedTime 5584  246
    -1  2612  4394  pxCompletedBy 930 56
    1287313579  2628  4578  pxIsComplete  4610  56
    -141500821  2644  2028  pyLabel 3840  2086
    1678852722  2660  4718  pxProcessName 3840  56
    -1627200217 2676  4782  pxStartTime 5638  246

  Page at index 11, offset: 2582
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 4 Hash table offset - 1012
    Bucket index  PropertyEntry Offset
    1 0
    2 1
    6 2

    Hash  Offset  Name Index  Name  Value Attr
    -1  2710  1152  pxObjClass  4834  1312
    -1  2726  4886  pxStepType  5692  56
    -141500821  2742  2028  pyLabel 5716  2086
    -761011953  2758  4992  pxStepID  5760  56

  Page at index 12, offset: 2664
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 4 Hash table offset - 1048
    Bucket index  PropertyEntry Offset
    1 0
    2 1
    6 2

    Hash  Offset  Name Index  Name  Value Attr
    -1  2792  1152  pxObjClass  4834  1312
    -1  2808  4886  pxStepType  4914  56
    -141500821  2824  2028  pyLabel 5786  2086
    -761011953  2840  4992  pxStepID  5830  56

  Page at index 13, offset: 2746
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 1 Hash table offset - 1084
    Bucket index  PropertyEntry Offset
    0 0

    Hash  Offset  Name Index  Name  Value Attr
    -1  2874  6034  pzInternalCaseFlow  14  7862

  Page at index 14, offset: 2780
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 25 Hash table offset - 1096
    Bucket index  PropertyEntry Offset
    3 0
    14  1
    15  2
    16  5
    17  7
    24  8
    27  9
    30  10
    31  11
    33  12
    34  13
    39  14
    40  15
    41  16
    47  17
    49  18
    50  20
    52  21
    56  22
    57  23
    59  24

    Hash  Offset  Name Index  Name  Value Attr
    -1  2908  7336  pxIsInvestigative 1592  5218
    -1  2924  7424  pyFirstRun  1592  400
    -1460562911 2940  6368  pyFlowParameters  15  6592
    924947515 2956  7056  pyFlowCalledCount 3536  2564
    -352290006  2972  7452  pxAssignIsVirtual 384 5218
    -1456680327 2988  6984  pyLastFlowStep  5016  738
    1591566331  3004  7378  pyLastFlowStepLabel 6756  738
    -1  3020  7700  pxTimeFlowStarted 7742  56
    -1  3036  7098  pxFlowInsKey  7130  56
    -1  3052  6614  pyDraftMode 1592  400
    -1  3068  6078  pyDeferCommit 1592  400
    -1  3084  7674  pxRouteTo 6458  56
    -1  3100  1282  pxSubscript 6034  1312
    -1  3116  6166  pxAssignActivity  6206  56
    -1  3132  6644  pyFlowPath  5 6916
    -1  3148  6266  pyContexts  -1  6294
    -1  3164  7264  pxAssignClass 7298  56
    -1  3180  7494  pyDeferErrors 1592  400
    -1870149154 3196  7020  pxLastUpdateBy  1000  56
    -875479254  3212  7796  pxAssignmentKey 614 56
    -1  3228  7528  pxSystemFlow  384 5218
    -1  3244  7614  pyCategory  7642  738
    -1  3260  7834  pyFlowType  6034  738
    -1  3276  1152  pxObjClass  7560  1312
    -1  3292  6112  pyFlowInterestPageClass 3876  738

  Page at index 15, offset: 3198
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 4 Hash table offset - 1356
    Bucket index  PropertyEntry Offset
    0 0
    4 1
    5 2
    6 3

    Hash  Offset  Name Index  Name  Value Attr
    -1  3326  6498  ReferencePageName 6540  1312
    -1  3342  6408  isNewCase 384 1312
    -1  3358  6568  flowName  6034  1312
    -1  3374  6434  AssignTo  6458  1312

  Page at index 16, offset: 3280
  Status: Y Reference Properties Marker : N Transient Properties Marker : N Msgs Offset: -1  
                                            Num entries: 6 Hash table offset - 1392
    Bucket index  PropertyEntry Offset
    0 0
    1 2
    2 3
    4 4
    6 5

    Hash  Offset  Name Index  Name  Value Attr
    1632482175  3408  6726  pyStepLabel 6756  738
    1254365144  3424  6874  pyFAProcessOnJump 1592  400
    -1  3440  1152  pxObjClass  6672  1312
    -1  3456  6846  pyFlowStep  5016  738
    -1  3472  6792  pyDisplay 1592  400
    -1  3488  6818  pyStepType  4914  738

Page List Section
  Section length: 88
  Offsets relative to: 13348
  Num page list indexes: 6
    0) 0
    1) 12
    2) 20
    3) 28
    4) 36
    5) 48

  Page List at index 0, offset: 0
    0) Page index: 6
    1) Page index: 9

  Page List at index 1, offset: 12
    0) Page index: 7

  Page List at index 2, offset: 20
    0) Page index: 8

  Page List at index 3, offset: 28
    0) Page index: 10

  Page List at index 4, offset: 36
    0) Page index: 11
    1) Page index: 12

  Page List at index 5, offset: 48
    0) Page index: 16

Messages Section
  Section length: 8
  Messages entries offsets relative to: 13412

    Num page indexes: 0 (Page_Index Offset)

String Section
  Section length: 9812
  Num entries: 266
  Offsets relative to: 3512
    Offset  Length  Value
  0) 0  32  -1  pxUpdateSystemID
  1) 40 8 -1  pega
  2) 56 14  -1  @Z:sTY:
  3) 78 44  -1  pyAttachmentCategories
  4) 130  14  -1  @Z:lTN:
  5) 152  32  -1  pxUpdateDateTime
  6) 192  46  -1  20180215T094141.341 GMT
  7) 246  14  -1  @Z:sMY:
  8) 268  38  -1  pyStatusCustomerSat
  9) 314  6 -1  New
  10) 328 18  -1  @Z:stN32:
  11) 354 22  -1  pyShowCases
  12) 384 8 -1  true
  13) 400 14  -1  @Z:sSN:
  14) 422 38  -1  pxUrgencyPartyTotal
  15) 468 2 -1  0
  16) 478 14  -1  @Z:sRY:
  17) 500 28  -1  pxCurrentStage
  18) 536 10  -1  PRIM2
  19) 554 52  -1  pyInternalAssignmentHandle
  20) 614 116 -397486101  ASSIGN-INTERNAL DMORG-DMSAMPLE-WORK A-3!PZINTERNALCASEFLOW
  21) 738 14  -1  @Z:sTN:
  22) 760 32  -1  pxCreateDateTime
  23) 800 46  -1  20180215T093420.451 GMT
  24) 854 22  -1  pyWorkParty
  25) 884 10  -1  Owner
  26) 902 20  -1  pyFullName
  27) 930 26  -1  Administrator
  28) 964 28  -1  pyWorkPartyUri
  29) 1000  44  -1  Administrator@pega.com
  30) 1052  22  -1  pxPartyRole
  31) 1082  14  -1  @Z:sIN:
  32) 1104  22  -1  pyAddresses
  33) 1134  10  -1  Email
  34) 1152  20  -1  pxObjClass
  35) 1180  36  -1  Data-Address-Email
  36) 1224  14  -1  @Z:sIY:
  37) 1246  28  -1  pyEmailAddress
  38) 1282  22  -1  pxSubscript
  39) 1312  14  -1  @Z:s?N:
  40) 1334  38  -1  @Z:S*NData-Address:
  41) 1380  38  -1  @Z:G*NData-Address:
  42) 1426  38  -1  Data-Party-Operator
  43) 1472  20  -1  pyUserName
  44) 1500  34  -1  pyCorrPreferences
  45) 1542  8 -1  <binary>
  46) 1554  30  -1  pyPartyNotified
  47) 1592  10  -1  false
  48) 1610  32  -1  pyUserIdentifier
  49) 1650  22  -1  pyFirstName
  50) 1680  24  -1  pyPartyLabel
  51) 1712  30  -1  pzIndexOwnerKey
  52) 1750  46  -1  DMORG-DMSAMPLE-WORK A-3
  53) 1804  36  -1  pyPartyClassPrompt
  54) 1848  20  -1  Case Owner
  55) 1876  18  -1  pzIndexes
  56) 1902  16  -1  PartyURI
  57) 1926  14  -1  @Z:sNY:
  58) 1948  14  -1  @Z:gNY:
  59) 1970  50  -1  pyPartyRoleVisibleOnEntry
  60) 2028  14  -1  pyLabel
  61) 2050  28  -1   Administrator
  62) 2086  18  -1  @Z:sTN64:
  63) 2112  16  -1  pyEmail1
  64) 2136  34  -1  @Z:S*IData-Party:
  65) 2178  34  -1  @Z:G*IData-Party:
  66) 2220  36  -1  pyConfirmationNote
  67) 2264  48  -1  Thank you for your input
  68) 2320  18  -1  pxInsName
  69) 2346  6 -1  A-3
  70) 2360  36  -1  pxUrgencyWorkClass
  71) 2404  4 -1  10
  72) 2416  52  -1  pyPushNotificationsEnabled
  73) 2476  28  -1  pxSaveDateTime
  74) 2512  26  -1  MaximumIncome
  75) 2546  10  -1  37500
  76) 2564  14  -1  @Z:sNN:
  77) 2586  34  -1  pyTemporaryObject
  78) 2628  16  -1  pzInsKey
  79) 2652  38  -1  pyNotifyQuickStream
  80) 2698  34  -1  QuestionAboutItem
  81) 2740  20  -1  pyOwnerOrg
  82) 2768  16  -1  pega.com
  83) 2792  18  -1  @Z:sTN32:
  84) 2818  20  -1  pyLabelOld
  85) 2846  48  -1  Credit Limit Application
  86) 2902  24  -1  pyOrigUserID
  87) 2934  30  -1  pyStatusWorkOld
  88) 2972  34  -1  Resolved-Accepted
  89) 3014  38  -1  pyElapsedStatusOpen
  90) 3060  14  -1  @Z:sRN:
  91) 3082  26  -1  pyAgeFromDate
  92) 3116  14  -1  @Z:sMN:
  93) 3138  36  -1  pyElapsedStatusNew
  94) 3182  10  -1  440.0
  95) 3200  24  -1  pxLockHandle
  96) 3232  28  -1  pxUpdateOpName
  97) 3268  30  -1  pxUpdateCounter
  98) 3306  2 -1  5
  99) 3316  20  -1  pyFlowName
  100) 3344 22  -1  pyStartCase
  101) 3374 32  -1  pxUpdateOperator
  102) 3414 46  -1  pxCurrentStageSubscript
  103) 3468 14  -1  PRIM2_2
  104) 3490 38  -1  pyNextEmailThreadID
  105) 3536 2 -1  1
  106) 3546 24  -1  pyStatusWork
  107) 3578 28  -1  pyWorkIDPrefix
  108) 3614 4 -1  A-
  109) 3626 28  -1  pyOrigDivision
  110) 3662 28  -1  Administration
  111) 3698 28  -1  pyResolvedTime
  112) 3734 52  -1  pyShowCompletedAssignments
  113) 3794 38  -1  pxCurrentStageLabel
  114) 3840 28  -1  Recommendation
  115) 3876 84  -352365662  DMOrg-DMSample-Work-CreditLimitApplication
  116) 3968 18  -1  pyOrigOrg
  117) 3994 32  -1  pxCreateSystemID
  118) 4034 38  -1  LoadingCustomerData
  119) 4080 20  -1  MaximumAge
  120) 4108 4 -1  30
  121) 4120 38  -1  pyOrigUserWorkgroup
  122) 4166 14  -1  Default
  123) 4188 24  -1  pzIndexCount
  124) 4220 28  -1  pxStageHistory
  125) 4256 36  -1  Embed-StageHistory
  126) 4300 32  -1  pxEnterStageTime
  127) 4340 46  -1  20180215T093420.467 GMT
  128) 4394 26  -1  pxCompletedBy
  129) 4428 22  -1  pxStageName
  130) 4458 24  -1  Call Context
  131) 4490 22  -1  pxProcesses
  132) 4520 50  -1  Embed-StageProcessHistory
  133) 4578 24  -1  pxIsComplete
  134) 4610 8 -1  True
  135) 4626 30  -1  pxCompletedTime
  136) 4664 46  -1  20180215T094137.808 GMT
  137) 4718 26  -1  pxProcessName
  138) 4752 22  -1  CallContext
  139) 4782 22  -1  pxStartTime
  140) 4812 14  -1  pxSteps
  141) 4834 44  -1  Embed-StageStepHistory
  142) 4886 20  -1  pxStepType
  143) 4914 20  -1  ASSIGNMENT
  144) 4942 42  -1  Increase Credit Limit
  145) 4992 16  -1  pxStepID
  146) 5016 24  -1  ASSIGNMENT63
  147) 5048 58  -1  @Z:L*YEmbed-StageStepHistory:
  148) 5114 16  -1  pxFlowID
  149) 5138 10  -1  FLOW2
  150) 5156 22  -1  pxStartedBy
  151) 5186 24  -1  pxIsOptional
  152) 5218 14  -1  @Z:sSY:
  153) 5240 64  -1  @Z:L*YEmbed-StageProcessHistory:
  154) 5312 22  -1  pxStageType
  155) 5342 14  -1  Primary
  156) 5364 18  -1  pxStageID
  157) 5390 10  -1  PRIM1
  158) 5408 14  -1  PRIM1_1
  159) 5430 40  -1  pxCompletedStageTime
  160) 5478 46  -1  20180215T094137.809 GMT
  161) 5532 16  -1  pxWentTo
  162) 5556 20  -1  pxCameFrom
  163) 5584 46  -1  20180215T094141.340 GMT
  164) 5638 46  -1  20180215T094137.811 GMT
  165) 5692 16  -1  DECISION
  166) 5716 36  -1  Credit Application
  167) 5760 18  -1  Decision1
  168) 5786 36  -1  Accept Application
  169) 5830 22  -1  Assignment1
  170) 5860 10  -1  FLOW0
  171) 5878 50  -1  @Z:L*YEmbed-StageHistory:
  172) 5936 56  -1  pyElapsedCustomerUnsatisfied
  173) 6000 6 -1  0.0
  174) 6014 12  -1  pxFlow
  175) 6034 36  -1  pzInternalCaseFlow
  176) 6078 26  -1  pyDeferCommit
  177) 6112 46  -1  pyFlowInterestPageClass
  178) 6166 32  -1  pxAssignActivity
  179) 6206 52  -1  pzCreateInternalAssignment
  180) 6266 20  -1  pyContexts
  181) 6294 66  -1  @Z:G*NEmbed-PegaEPRO-FlowContext:
  182) 6368 32  -1  pyFlowParameters
  183) 6408 18  -1  isNewCase
  184) 6434 16  -1  AssignTo
  185) 6458 32  -1  default@pega.com
  186) 6498 34  -1  ReferencePageName
  187) 6540 20  -1  pyWorkPage
  188) 6568 16  -1  flowName
  189) 6592 14  -1  @Z:S*N:
  190) 6614 22  -1  pyDraftMode
  191) 6644 20  -1  pyFlowPath
  192) 6672 46  -1  Embed-PegaEPRO-FlowPath
  193) 6726 22  -1  pyStepLabel
  194) 6756 28  -1  Perform action
  195) 6792 18  -1  pyDisplay
  196) 6818 20  -1  pyStepType
  197) 6846 20  -1  pyFlowStep
  198) 6874 34  -1  pyFAProcessOnJump
  199) 6916 60  -1  @Z:L!NEmbed-PegaEPRO-FlowPath:
  200) 6984 28  -1  pyLastFlowStep
  201) 7020 28  -1  pxLastUpdateBy
  202) 7056 34  -1  pyFlowCalledCount
  203) 7098 24  -1  pxFlowInsKey
  204) 7130 126 1894511949  RULE-OBJ-FLOW WORK- PZINTERNALCASEFLOW #20151105T160214.591 GMT
  205) 7264 26  -1  pxAssignClass
  206) 7298 30  -1  Assign-Internal
  207) 7336 34  -1  pxIsInvestigative
  208) 7378 38  -1  pyLastFlowStepLabel
  209) 7424 20  -1  pyFirstRun
  210) 7452 34  -1  pxAssignIsVirtual
  211) 7494 26  -1  pyDeferErrors
  212) 7528 24  -1  pxSystemFlow
  213) 7560 46  -1  Embed-PegaEPRO-FlowPage
  214) 7614 20  -1  pyCategory
  215) 7642 24  -1  FlowStandard
  216) 7674 18  -1  pxRouteTo
  217) 7700 34  -1  pxTimeFlowStarted
  218) 7742 46  -1  20180215T093420.463 GMT
  219) 7796 30  -1  pxAssignmentKey
  220) 7834 20  -1  pyFlowType
  221) 7862 60  -1  @Z:S*YEmbed-PegaEPRO-FlowPage:
  222) 7930 60  -1  @Z:G*YEmbed-PegaEPRO-FlowPage:
  223) 7998 26  -1  pxApplication
  224) 8032 16  -1  DMSample
  225) 8056 24  -1  UnlimitedSMS
  226) 8088 32  -1  pxCoveredInsKeys
  227) 8128 14  -1  @Z:lTY:
  228) 8150 46  -1  pyCaseFilterDescription
  229) 8204 64  -1  Current Assignments and Subcases
  230) 8276 26  -1  pxUrgencyWork
  231) 8310 42  -1  pyStatusWorkTimestamp
  232) 8360 46  -1  20180215T094141.342 GMT
  233) 8414 26  -1  pyOrigOrgUnit
  234) 8448 24  -1  Installation
  235) 8480 36  -1  pxCoveredCountOpen
  236) 8524 26  -1  pyOwnerUserID
  237) 8558 28  -1  pyOwnerOrgUnit
  238) 8594 44  -1  pyElapsedStatusPending
  239) 8646 34  -1  pyWorkPartiesRule
  240) 8688 46  -1  pyCaseManagementDefault
  241) 8742 50  -1  pxCoveredCountUnsatisfied
  242) 8800 26  -1  MinimumIncome
  243) 8834 10  -1  20000
  244) 8852 42  -1  pyShowOpenAssignments
  245) 8902 58  -1  pySatisfactionChangeTimestamp
  246) 8968 46  -1  20180215T093420.476 GMT
  247) 9022 20  -1  MinimumAge
  248) 9050 4 -1  18
  249) 9062 30  -1  pxUpdateOrgUnit
  250) 9100 18  -1  @Z:sTY32:
  251) 9126 10  -1  FourG
  252) 9144 8 -1  pyID
  253) 9160 30  -1  pyOwnerDivision
  254) 9198 50  -1  pxSystemUpdateDetailsList
  255) 9256 46  -1  @Z:L*YEmbed-CaseUpdate:
  256) 9310 28  -1  pxCoveredCount
  257) 9346 26  -1  International
  258) 9380 36  -1  pyOrigUserDivision
  259) 9424 32  -1  pxCreateOperator
  260) 9464 24  -1  pyFolderType
  261) 9496 18  -1  pyDefault
  262) 9522 18  -1  @Z:sIN32:
  263) 9548 18  -1  pyFlowKey
  264) 9574 186 -981782260  RULE-OBJ-FLOW DMORG-DMSAMPLE-WORK-CREDITLIMITAPPLICATION 
                            PYSTARTCASE #20150114T150632.196 GMT
  265) 9768 28  -1  pxCreateOpName

Reusable area information
   Orphan(Reusable) page entry offsets : 
   Orphan(Reusable) pagelist entry offsets : 
   Potential orphan strings bytes : 0

2 thoughts on “How to Read Pega 7 BLOB (Storage Stream)

  1. Such a clear explanation of what goes inside Pega. We tried the same to extract the class files and use it to build a standalone app to extract blob info. But we are facing few issues with this approach.
    1. We are unable to see the source code of those class files using enhanced class decompiler. May be the code is obfuscated.
    2. Secondly, We are unable to run this inflater code in the java program. It shows the following error. com.pega.pegarules.data.internal.clipboard.directstream.BadStreamDataException: Problem decompressing a storage stream
    at com.pega.pegarules.data.internal.clipboard.directstream.InflaterV7.inflateV7(InflaterV7.java:94)
    at clsDecompress.main(clsDecompress.java:47)
    Caused by: java.util.zip.DataFormatException: incorrect header check
    at java.util.zip.Inflater.inflateBytes(Native Method)
    at java.util.zip.Inflater.inflate(Unknown Source)

    Any way we can get rid of this issue?

    • Hello,

      thanks for the comment. For 1, can you provide more details? What kind of Pega distribution are you using? In my post, I used the exercise system.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.