Imagine this scenario: you have an Archiver configuration that writes output to a file share and the disk is full, so the Archiver doesn't get to finish. Or perhaps your configuration pushes data to an external service and that service is not available during the process, so it cannot complete. Generally, the Archiver won't give you an option to retry these connections so your batches will be sitting in a failed state, e.g. 541. Normally you would need to reprocess these jobs and ODEE provides a web service API (DoPublishFromFactory) for just that purpose. However, there may be special cases (such as user-modified or user-entered data) in Documaker Interactive that might make this an unfeasible approach. In cases such as these we can manually kickstart these transactions, much like pouring a bit of gasoline into a carburetor to start a normally-aspirated combustion engine. Note: this analogy is good, because pouring gasoline in a carburetor can be dangerous, and messing around under the hood of ODEE can be dangerous too so remember to backup your database before making changes, or play around in a sandbox environment.

Before we dive in, let's do a quick review: in normal processing, units of work in the ODEE database progress through a series of status codes. The hundreds position of the status code indicates the Worker that is processing the unit of work, e.g. 121 (1 in the hundreds position) is a Receiver work unit. The tens and ones position indicates the disposition, e.g. 241 is an error in the Assembler. The basic status codes are:

  • x11 – Ready for Worker
  • x21 – In Progress (Waiting for Worker)
  • x31 – In Progress (Worker Accepted)
  • x41 – Error
  • 416 – Batching Scheduled (Waiting for Batch Closing)
  • 999 – All Work Completed

You can view the list of codes in the Documaker Administrator application by selecting the Assembly Line, and clicking Configure, and then expanding the Status-CFG context and clicking the Status Group. You can review the process flow of workers and status codes in the Documaker Enterprise Administrator Guide starting on page 132, Using the Scheduler. With that completed, we need to review our situation. In my failed scenario, I have a scheduled batch that closed and was processed by the Archiver, but my receiving service on the other end was down, and my batch status is Archiver-Error (541). If I have corrected my failure situation, I want to reprocess this batch through the archiver.

First, I need to validate that everything is present, that is, all publications for the batch have been generated. I can use the Dashboard to locate by batch identifier, aka BCH_ID. Once we know this value, we can query the database for the total number of records present in the batch. You will need a SQL query tool and write access to the DMKR_ASLINE schema to continue.

SELECT COUNT(*) as "BATCH ENTRIES" FROM BCHS_RCPS WHERE BCH_ID=1;

+-------------+
|BATCH ENTRIES|
+-------------+
|3            |
+-------------+

Next, we want to make sure that we have the same number of PUBS rows as we do batch entries

SELECT COUNT(*) as "PUBS ENTRIES" FROM BCHS_RCPS WHERE PUB_ID is not null and BCH_ID=1;
+------------+
|PUBS ENTRIES|
+------------+
|3           |
+------------+

If the numbers match, then the Presenter properly generated the publications necessary for the Archiver. If the numbers do not match, the Presenter failed to generate all of the required publications – if this is the case you need to stop and figure out what's going on. Otherwise you can continue. 

The next step is to validate that the publications are in fact in error status:

SELECT PUBSTATUS FROM PUBS WHERE PUB_ID IN (SELECT PUB_ID FROM BCHS_RCPS WHERE BCH_ID=1);
+---------+
|PUBSTATUS|
+---------+
|541      |
+---------+
This is what we expect, so we can continue. If the PUBSTATUS was anything other than 541 we need to make sure reprocessing is necessary, because another status may indicate the transaction and job has a different disposition than our assumption. 
 
The next step is tedious as we have to update each of the components from the JOB on down to the PUB to a pre-Archiver state. First, we check the current TRNS status:
SELECT TRNSTATUS,COUNT(TRN_ID) FROM TRNS WHERE TRN_ID IN (SELECT TRN_ID FROM BCHS_RCPS WHERE BCH_ID = 1) GROUP BY TRNSTATUS;
+---------+-------------+
|TRNSTATUS|COUNT(TRN_ID)|
+---------+-------------+
|541      |1            |
+---------+-------------+
Now we update the TRNSTATUS value to 416. Replace the TRNSTATUS IN caluse of 541 with the above value, if it is different. 
UPDATE TRNS SET TRNSTATUS=416 WHERE TRN_ID IN (
    SELECT TRN_ID FROM TRNS WHERE TRN_ID IN
                                  (SELECT TRN_ID FROM BCHS_RCPS WHERE BCH_ID = 1) and
            TRNSTATUS IN (541));
commit;

Technically the final clause is not necessary, but I like to be precise in what I'm updating.

Next, we perform the same operation for the JOBS records — query, then update:

SELECT JOBSTATUS,COUNT(JOB_ID) FROM JOBS WHERE JOB_ID IN (SELECT JOB_ID FROM BCHS_RCPS WHERE BCH_ID = 344) GROUP BY JOBSTATUS;
+---------+-------------+
|JOBSTATUS|COUNT(JOB_ID)|
+---------+-------------+
|541      |1            |
+---------+-------------+
UPDATE JOBS SET JOBSTATUS=416 WHERE JOB_ID IN (
    SELECT JOB_ID FROM JOBS WHERE JOB_ID IN
    (SELECT JOB_ID FROM BCHS_RCPS WHERE BCH_ID = 1) and
    JOBSTATUS IN (541)
    );
commit;
The end is in sight as we perform the query and update for PUBS:
SELECT PUBSTATUS,COUNT(*) FROM PUBS WHERE PUB_ID IN (SELECT PUB_ID FROM BCHS_RCPS WHERE BCH_ID=344) GROUP BY PUBSTATUS;
+---------+--------+
|PUBSTATUS|COUNT(*)|
+---------+--------+
|541      |1       |
+---------+--------+
UPDATE PUBS SET PUBSTATUS = 490 WHERE PUB_ID IN (
     SELECT PUB_ID FROM BCHS_RCPS WHERE BCH_ID = 1);
commit;
Note: You may be wondering why this count does not match our previous query of PUB_ID, and that's because all of the output was routed into a single publication. You can verify this by looking at the BCHS_RCPS.PUB_ID value for your BCH_ID, and you'll find that, in this case, they are all the same PUB_ID.
 
And BCHS…
UPDATE BCHS SET BCHSTATUS = 521 WHERE BCH_ID = 1;
COMMIT;
And finally, BCHS_RCPS:
UPDATE BCHS_RCPS SET BCHRCPSTATUS = 511 WHERE BCH_ID = 1;
commit;
Now the records reflect the state prior to Archiver execution. Before you continue, you must:
  • Make sure Archiver is running
  • Have access to the WebLogic Console
  • Have access to the server where WebLogic is running

Here is where it gets a little interesting. The Scheduler is responsible for pushing work units into the Archiver, and it does so by placing an XML job ticket into a JMS message queue. We are going to create a message and place it into the JMS queue. To do that, we need to know the BCH_ID, which we already have, and a JOB_ID, which we might have, but can get easily:

select JOB_ID from BCHS_RCPS where bch_id = 344;
+------+
|JOB_ID|
+------+
|1     |
|1     |
|1     |
+------+
If there were multiple JOB_IDs, we would need to make multiple tickets, but in this case there is just one unique JOB_ID. The ticket is XML, which you can edit in a standard text editor and place in the BCH_ID and JOB_ID values.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BatchTicket xmlns="oracle/documaker/schema/tables/bchs">
<BCH_ID>1</BCH_ID>
<JOB_ID>1</JOB_ID>
<CORRELATION_ID></CORRELATION_ID></BatchTicket>

Next, you'll need to base-64 encode the XML using a base-64 encoder, such as base64encode.org, and you'll have something like this:

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8QmF0Y2hUaWNrZXQgeG1sbnM9Im9yYWNsZS9kb2N1bWFrZXIvc2NoZW1hL3RhYmxlcy9iY2hzIj4KPEJDSF9JRD4xPC9CQ0hfSUQ+CjxKT0JfSUQ+MTwvSk9CX0lEPgo8Q09SUkVMQVRJT05fSUQ+PC9DT1JSRUxBVElPTl9JRD48L0JhdGNoVGlja2V0Pg==

Now, we will create the JMS message. Create a text file on your WebLogic Server, ideally in the root directory of the ODEE domain. Place your base-64 encoded string in the file where indicated.
 
<?xml version="1.0" encoding="UTF-8"?>
<JMSMessageExport>
    <mes:WLJMSMessage xmlns:mes="http://www.bea.com/WLS/JMS/Message">
        <mes:Header>
            <mes:JMSMessageID>ID:&lt;653013.1634654289053.0&gt;</mes:JMSMessageID>
            <mes:JMSDeliveryMode>PERSISTENT</mes:JMSDeliveryMode>
            <mes:JMSExpiration>0</mes:JMSExpiration>
            <mes:JMSPriority>4</mes:JMSPriority>
            <mes:JMSRedelivered>false</mes:JMSRedelivered>
            <mes:JMSTimestamp>1634654289053</mes:JMSTimestamp>
            <mes:Properties>
                <mes:property name="JMS_BEA_DeliveryTime">
                    <mes:Long>1634654289053</mes:Long>
                </mes:property>
                <mes:property name="JMSXDeliveryCount">
                    <mes:Int>0</mes:Int>
                </mes:property>
            </mes:Properties>
        </mes:Header>
        <mes:Body>
<mes:Bytes>******* put your base-64 encoded string here ******</mes:Bytes>
        </mes:Body>
    </mes:WLJMSMessage>
</JMSMessageExport>
Finally, login to the WebLogic Console, and navigate to Services > Messaging > JMS Modules > AL1Module > ArchiverReq > Monitoring. Here, tick the box to the queue name, and click Show Messages.
 
PastedGraphic-3.png
 

Click Import and locate the text file you created, select the radio button next to it and click OK.

PastedGraphic-2.png
 
If all goes well, the batch will be processed by the Archiver immediately, and the destinations in the batch should contain the appropriate output. Happy batching!