X

Technical info and insight on using Oracle Documaker for customer communication and document automation

Using SoapUI to Enhance DWS Testing

Andy Little
Technical Director

If you're using Oracle Documaker Enterprise Edition (ODEE), there's a good chance that you're already using Documaker Web Service (DWS) with your implementation. And, it's quite possible that if you're using DWS, you've already toyed with using Smart Bear's popular SOAP testing tool SoapUI to perform basic validation that DWS is working. You might even be using SoapUI to test more advanced features such as WS-Addressing (WSA) or WS-Security (WSS). But... did you know that you can use SoapUI to enhance your unit and regression testing? In this article, I'm going to go over some some fundamentals for using SoapUI in this capacity.

First, before we get too far, you're going to want an ODEE environment so you can test your specific requirements. In my examples I am using the reference implementation which comes with all ODEE installations and although actually deploying it is not required, it's a good way to validate that your environment is up and running. If you don't have an ODEE environment, you can set one up using these posts as a reference. If you don't have all the prerequisites available, you can download a WebCenter Content preview VM and install ODEE there to use as an evaluation. Once you have your ODEE environment, you'll need to know the endpoint of your DWS services, which you can find in the WebLogic Console: login to your console and navigate to Domain Structure > Deployments > DWSAL1 (expand) > PublishingServiceSoap12 (Module DWSAL1) > Testing. Then expand the PublishingServiceSoap12, and note the WSDL link. Note: you can use the PublishingService or the PublishingServiceSoap12. The functionality is exactly the same, however the format of the messages differs (SOAP 1.1 and SOAP 1.2, respectively), so you must be consistent in that if you pick the Soap12 endpoint, you need to use the Soap12 Binding in SoapUI project below. Also FYI, if you happen to have any web front ends such as Oracle HTTP Server, that will not be taken into account on this link. 

locating the WSDL endpoint for DWS services in WebLogic console.

Next, you'll want to have some information about your particular implementation of ODEE: the assembly lines, extract files, and batching configuration. Not all of this information is necessary, but depending on the type of use case you want to create, you'll want to make sure you have the appropriate extract file samples to trigger the test conditions you want to exercise. In my examples, I'm going to validate the functionality of the LOCALPRINT batching, which simply generates PDF output. To do that, I need an extract file that is known to trigger recipients for the LOCALPRINT batching. The reference implementation includes some default batchings and extract files which are well-suited for this need. The batchings can be reviewed in Documaker Administrator and the extract files are provided in the DocFactory installation under ODEE_HOME/documaker/mstrres/dmres/input.

Documaker Administrator list of Batchings

Finally, you need to download and install SoapUI. Once this is done, start up SoapUI and click the SOAP Button. Enter a name for the project, the WSDL endpoint for the Publishing Service (note that you can use the PublishingService or the PublishingServiceSoap12 WSDL endpoints here, and you can even add them both). Tick the box to create sample results and click Ok.

Create new SOAP Project

Now, expand the nodes of your project and look for PublishingServiceSoap12Binding > doPublishFromImport > Request 1. You'll see here that SoapUI has built a sample request based on all possible values that could be submitted, and I mean all. We don't need most of these, but you might explore the possibilities here before moving on. For now, delete the contents of the request and replace it with this:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pub="oracle/documaker/schema/ws/publishing" xmlns:com="oracle/documaker/schema/ws/publishing/common" xmlns:v1="oracle/documaker/schema/ws/publishing/doPublishFromImport/v1" xmlns:com1="oracle/documaker/schema/common" xmlns:req="oracle/documaker/schema/ws/publishing/doPublishFromImport/v1/request">
   <soap:Header/>
   <soap:Body>
      <pub:DoPublishFromImportRequest>
         <pub:DoPublishFromImportRequestV1>
            <v1:JobRequest CorrelationId="1">
               <req:Payload>
                  <req:Extract>
                     <com1:Content>
                        <com1:Binary>***REPLACE***</com1:Binary>
                     </com1:Content>
                  </req:Extract>
               </req:Payload>
            </v1:JobRequest>
            <v1:ResponseProperties>
               <com1:ResponseType>Identifiers</com1:ResponseType>
            </v1:ResponseProperties>
         </pub:DoPublishFromImportRequestV1>
      </pub:DoPublishFromImportRequest>
   </soap:Body>
</soap:Envelope>

The above represents the simplest request you can submit for processing -- note that there is something missing, and that is the base-64 encoded extract file. To insert that, remove the ***REPLACE*** text, and right-click at that point and select Insert File as Base 64. You can then locate the extract file and it will be encoded and inserted in place. That's it! 

Now you can run the request using the Play triangle button at the top left of the request window and if all goes well, you should see a response that looks something like XML below. Note that because we had <com1:ResponseType>Identifiers</com1:ResponseType> in our request, DWS is going to respond with the ID attributes for what was generated by the transaction, not the actual outputs. 

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
   <S:Body>
      <DoPublishFromImportResponse>
         <DoPublishFromImportResponseV1>
            <ns1:Result>0</ns1:Result>
            <ns1:ServiceTimeMillis>2324</ns1:ServiceTimeMillis>
            <ns2:ServerTimeMillis>2103</ns2:ServerTimeMillis>
            <ns2:JobResponse CorrelationId="1">
               <ns8:JobEndTime>2020-03-19T18:33:41.989Z</ns8:JobEndTime>
               <ns8:JobStartTime>2020-03-19T18:33:40.002Z</ns8:JobStartTime>
               <ns8:JobStatus>999</ns8:JobStatus>
               <ns8:Job_Id>400</ns8:Job_Id>
               <ns8:Payload>
                  <ns8:Transaction>
                     <ns8:Data>
                        <ns4:Content>
                           <ns4:Publication>
                              <ns4:BchId>396</ns4:BchId>
                              <ns4:PubId>608</ns4:PubId>
                              <ns4:PubMimeType>application/pdf</ns4:PubMimeType>
                              <ns4:PubPrtExt>pdf</ns4:PubPrtExt>
                           </ns4:Publication>
                        </ns4:Content>
                     </ns8:Data>
                     <ns8:Job_Id>400</ns8:Job_Id>
                     <ns8:TrnEndTime>2020-03-19T18:33:41.987Z</ns8:TrnEndTime>
                     <ns8:TrnName>Bill M Smith</ns8:TrnName>
                     <ns8:TrnStartTime>2020-03-19T18:33:40.027Z</ns8:TrnStartTime>
                     <ns8:TrnStatus>999</ns8:TrnStatus>
                     <ns8:Trn_Id>439</ns8:Trn_Id>
                  </ns8:Transaction>
               </ns8:Payload>
            </ns2:JobResponse>
            <ns2:ServiceInfo>
               <ns4:Operation>doPublishFromImport</ns4:Operation>
               <ns4:Version>
                  <ns4:Number>1</ns4:Number>
                  <ns4:Used>true</ns4:Used>
               </ns4:Version>
            </ns2:ServiceInfo>
         </DoPublishFromImportResponseV1>
      </DoPublishFromImportResponse>
  </S:Body>
</S:Envelope>

This has been truncated a bit to conserve space -- your results should have more information, but you can see that in the response you can obtain the TRNSTATUS=999 for all transactions in the job, some details about the publications created, and the JOBSTATUS=999. You can even get some details on the timing of the job processing. Next, right-click the Request 1 in the project navigator and select Clone Request, and name it Request 2. In this one, you can change the response properties slightly: change Identifiers to Attachments and rerun the request. You should notice that the response is much bigger than the previous request, and you should notice that there are some changes in the data in the response:

...
<ns8:Transaction>
 <ns8:Action>100017</ns8:Action>
 <ns8:ApprovalState>60</ns8:ApprovalState>
 <ns8:CreateTime>2020-03-19T19:32:26.000Z</ns8:CreateTime>
 <ns8:CurrGroup>3</ns8:CurrGroup>
 <ns8:CurrUser>8</ns8:CurrUser>
 <ns8:Customized>0</ns8:Customized>
 <ns8:Data>
    <ns4:Name>397_611</ns4:Name>
    <ns4:ContentType>application/pdf</ns4:ContentType>
      <ns4:FileType>pdf</ns4:FileType>
      <ns4:Content>
        <ns4:Binary> *** base-64 encoded data *** </ns4:Binary>
      </ns4:Content>
 </ns8:Data>
</ns8:Transaction>

Notice there's a new <Binary> node? That contains, as you might expect, the output publication generated by this request. And you can probably tell from the <FileType> and <ContentType> nodes that it is in fact a PDF, so if you base-64 decode the contents of the <Binary> element, you can view the PDF.  

By now you should understand that it's possible to create multiple requests, each with specific requirements for input and output, and you can execute these tests easily by storing the requests and manipulating them. Now we'll take it a step further and create a test suite where we can create iterative tests and validate them with assertions. To get started:

  • Right click the project node in SoapUI and select New TestSuite, and give it a name.
  • Right click the newly-created TestSuite, select New TestCase, and give it a name.
  • Expand the newly-created TestCase, and right-click Test Steps and select Add Step > SOAP Request.
    • Specify a name for the request and click Ok.
    • In the dropdown, select PublishingServiceSoap12Binding -> doPublishFromImport and click Ok.
    • Name the request and tick the boxes for all validations. You can also tick the box to creation optional content, but this is not necessary as we'll be replacing all of it.
  • The request opens with the SOAP Request XML in view. Here, you can paste in the SOAP request XML from the previous Identifiers or Attachments request we tested earlier.
  • Bring the TestCase window to focus (you can double-click it in the Navigator) and click the Play button. You should see the results of the test populate in the response pane of the SOAP Request window. You should also see the TestCase results status as green and finished, meaning no errors!

You can also bring the TestSuite window into focus and click the Play button there, too. It will run all the TestCase items under it. I'm sure by now you're saying, "Ok, but this is exactly what I just did, so what's the point?" I get you. Hold on -- we're going to take things to the next level! Bring the TestCase window back into focus and look at the Properties panel in the Navigator, and click the Custom Properties button, click the + icon and name your property InputFile and give it a value of extract.xml

Next, right click the TestCase and select Add Step > Groovy Script, and name your script. In the Navigator, click and drag the script above the SOAP Request so it will execute before the request. In the Groovy Script window, paste in the following:

import javax.mail.util.ByteArrayDataSource;

def extractFile = testRunner.testCase.getPropertyValue("InputFile")
testRunner.testCase.setPropertyValue("InputFileBase64"testRunner.testCase.setPropertyValue("InputFileBase64","")

if (extractFile != "" && extractFile != null)
{
	String extractFilePath = getAbsolutePath(extractFile)
	String xmlstring = new File(extractFilePath).text
	testRunner.testCase.setPropertyValue("InputFileBase64",xmlstring.bytes.encodeBase64().toString())
}			
String getAbsolutePath(String relativePath) {
	def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
	def thePath = groovyUtils.projectPath + "/" + relativePath;
	return thePath;
 }

What does this do, exactly? Well, in short, it reads the value of TestCase property called InputFile (which we set to extract.xml) and then it will read that file and base-64 encode it, and store that in a TestCase property called InputFileBase64. Now we just need to use it! in your SOAP Request window, replace the contents of the <Binary> node with this:

${#TestCase#InputFileBase64}

So your request should look like this:

css<soap:envelope xmlns:com="oracle/documaker/schema/ws/publishing/common" xmlns:com1="oracle/documaker/schema/common" xmlns:pub="oracle/documaker/schema/ws/publishing" xmlns:req="oracle/documaker/schema/ws/publishing/doPublishFromImport/v1/request" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="oracle/documaker/schema/ws/publishing/doPublishFromImport/v1">
   <soap:header>
   <soap:body>
      <pub:dopublishfromimportrequest>
         <pub:dopublishfromimportrequestv1>
            <v1:jobrequest correlationid="1">
               <req:payload>
                  <req:extract>
                     <com1:content>
                        <com1:binary>${#TestCase#InputFileBase64}</com1:binary>
                     </com1:content>
                  </req:extract>
               </req:payload>
            </v1:jobrequest>
            <v1:responseproperties>
               <com1:responsetype>Attachments</com1:responsetype>
            </v1:responseproperties>
         </pub:dopublishfromimportrequestv1>
      </pub:dopublishfromimportrequest>
   </soap:body>
</soap:header></soap:envelope>

At this point you should save your project file using the Save All button on the menu bar. Note carefully where you save the project file. Now, take your extract file and place it in the same directory as the project file, and name it with the value you set in the InputFile property. Now if you run the TestCase again, you should see two steps completed:

You can click on the Step links to bring up the results of each step, and see the response message using the Response Message button.

So, what just happened? When we ran the test case, the Groovy Script read the InputFile property to get the name of the extract file we wanted. We passed that name to a function so we could get the full path of the file, then we loaded that file and base-64 encoded it. We wrote that encoded string to another TestCase property. The next step in the case is to submit the request. Remember when we changed the extract data in the request to the placeholder ${#TestCase#InputFileBase64}? SoapUI automatically replaced our placeholder with actual data. In this case, the syntax of the placeholder indicates a TestCase custom property called InputFileBase64. We can see immediately that the green check marks indicate our tests were successful. If you got errors, use the SoapUI Log, error log, and script log buttons at the bottom of the SoapUI window to review and debug. Along the way you might be asking "what is Groovy?" and the short answer it's a Java-compatible scripting language, and there are plenty of reasons to use it, not least of which is that it's what SoapUI uses for scripting. How can we take advantage of it? Read on!

I'm certain you recall that we can use <ResponseType>Attachments</ResponseType> to return a PDF of our transaction, but then we have to go through the trouble of opening the response, copying the base-64 encoded string, pasting it into a decoder, saving that to a file and then opening it. Tedium! What if you could write a script that parses the response and does all of that for you? You can! In fact, I've made this easy. I've built a SoapUI project that you can download from my Github repository. In it, you'll find that I've created two test cases: Local Print - Attachments and Local Print - Identifiers. Each of these test cases has three test steps, and those steps call a third disabled test cases so that they share common code and can be executed simultaneously. Review the steps for all three cases and you'll find that:

  • input files are expected to be in an input folder at the same level as the SoapUI project file;
  • extract file for each test case is named by the test case custom property InputFile;
  • test cases which generate attachments will go into an output folder at the same level as the SoapUI project file;
  • attachments will be written into an output subfolder with a time date stamp;
  • attachments will be written with the configured name that ODEE uses to name the publication;
  • details from responses are written to a few test case custom properties

All you need to do with this project file to use it is:

  • replace the extract data with a file that matches your library and configuration (replace input/local_print.xml). If you are using this with the reference implementation, you don't need to change it.
  • change the endpoint to match your system (open the request and select it from the dropdown and click Edit Current and modify to match your system)

In future blog posts, I'll cover some more esoteric use cases with SoapUI such as WS-Addressing and WS-Security. For now, experiment with using Groovy Script to modify your extract data to fit multiple use cases, or try building a regression test suite that you can automate with SoapUI. Let me know in the comments about some of the interesting things you do with SoapUI and Documaker!

 

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.