Welcome to the OPA Hub!


Blog

Continuous Development – OPA and Postman, Newman and Jenkins #3

Continuous Development – OPA and Postman, Newman and Jenkins #3

Following on from the two previous episodes, (part one / part two) the stage is almost set to move to automation over and above the simple concept of a Postman Collection. In this chapter we will see how to use data files in Postman to facilitate making use of CSV or JSON data in a dynamic way, and we will get Newman up and running. So let’s start with the first element.

In our Collection, we currently have one request which is sending information to OPA and getting a journey time and plan back in response. Great. But we want to test our journey planner with more than one journey. And we want to be able to easily change the journeys without having to mess with our request. So this is where the ability to load data into a Collection from a text (CSV or JSON) file comes in very handy in deed. In pictures

  • Create a CSV file with your data in it. For the project used in this example we would need to have something like this

Collection Data File

Notice the headers are origin and destination. They will become variables that we need to add to our request.

  • Make sure that the request is updated

So now my request looks like this:

Request Modified

Don’t forget to save your request. Now if you go to Collection Runner and run your Collection, you can use the Select File button and select your file:

Using a Data File in Postman

As soon as you select the file, you will see that the number of iterations changes to take into account all the rows in your file. Now when you want to push a new set of journey tests all you need is to change that file. Awesome!

Armed with all of this, we can now move to the next challenge. Postman is great but not everyone wants to use the graphical user interface all the time. How about the ability to run a Collection from the command line? That would be great AND would open up lots of options to running Windows Scripts and the like. Well, the news is good. Newman is the CLI (Command Line Interface) for Postman. Setting it up if you are not familiar with Node.js can be a bit daunting, but let’s just make a shopping list first:

  1. Install Node.js (here)
  2. Install Newman using the Node Package Manager
    This step should be as easy as opening the Node Command Prompt (which got installed in your Windows Start Menu in the first part) and typing something like the following:

    Installing Newman

  3. Run Newman from the Node.js prompt to use Postman Runner with your chosen Collection and Data File using the ultra simple command line.

So the last step might look a little like the following – notice that in the command line you specify the Collection (which you must first export to a file from inside Postman) and the Data File (wherever it is – I put both files in the same location for ease of use. And once the job is done, Newman reports back with it’s own inimitable, Teletext-style display of the output. A word of advice – before exporting a Collection make sure you have saved all the recent changes!

Exporting Ready for Newman

 

Once the Collection is exported, you might run it like this. This is just a simple example. It is possible to also load environment variables and more to fine tune it.

Newman Command Line

After a few seconds we get the output from Newman. Note the 4 iterations, and that iteration 3 failed due to an excessively long journey time.

Newman Output in Teletext

Now this is of course a major step forward – running Collections from the command line, feeding in data sets just by using a simple command line switch – these features mean we can really now start to think of automation in our approach to testing this project. But we are not done yet. The output from Newman is pretty ugly and we need to change that. By installing Newman HTML Reporter, we can get a much nicer file. Follow the steps in the link and then change your example command line to something like this:

Note the new command line option -r html (which means, use the HTML reporter) and the –reporter-html-export option (with two dashes) which ensures the output file is stored in the folder of my choice. And the HTML output is so much better:

Newman HTML Reporter

What a nice document. So far so good. We can spin these collections with just a command line. But wait a minute, what about running tests when you are not in the office – sure, you could write yourself some sort of Powershell Script in Windows. But what if you wanted to run a set of tests every day at 3pm, then again on Tuesdays, then once on the first Monday of every second month…it would get quite hard. And what if you wanted to send the HTML Report automatically to all your colleagues on the testing team…but only if there were failures?

And so, we march onward to the next phase. See you shortly!

Continuous Development – OPA and Postman, Newman and Jenkins #2

Continuous Development – OPA and Postman, Newman and Jenkins #2

Following on from the previous post in this series, we now have Oracle Policy Automation and Postman playing nicely together. In this chapter we will use  some scripts in our Collection, both to streamline the authentication process and to provide us with some feedback about the execution of our collection.

So, first things first let’s add some scripts to our Postman Collection. In Postman there are two sorts of scripts, which you can think of as “before” and “after” scripts. For example you might run a script to prepare some data, or to authenticate your user with Oracle Policy Automation before you actually run a request. Similarly, after the test has run, you might investigate an output attribute from Oracle Policy Automation, or look at the response time of your request and compare it to others. That sort of thing. Let’s look at some useful examples. And just before we continue, remember that “before” and “after” scripts are available both at the Collection level as well as the individual Request level.

  1. Authenticating before the Collection is run

This is a common need  – to make sure the Collection can actually run without having to manually go and authenticate if your 1800 seconds are up. Of course more sophisticated scripts could store the current expiry and check to see if authentication is needed but this is just a simple example of how to authenticate. For example, you could paste this into your Pre-Request Script or your Pre-Collection Script:

var myVar = "?grant_type=client_credentials&client_id=YOURUSER&client_secret=YOURPASSWORD";
console.log("Updating Token");
pm.sendRequest({
url: "http://YOURSERVER/determinations-server/batch/auth" + myVar,
method: 'POST'
}, function (err, res) {
pm.environment.set("OAuth_Token", res.json().access_token);
});

This requires you also to set up a variable in your Environment in Postman called OAuth_Token, and also to ensure that your Collection knows to use it. Follow these steps.

  1. Create the Environment Variable by clicking the Eye icon and then Edit. Leave the value blank, your script will populate it automatically, Ignore the other variables in the screenshot they are not used by this simple script.
  2. Add the Script to manage the Variable.
  3. Add a reference to the new variable in Authentication.

So in pictures, first the Environment Variable to be added:

Postman Variables 3

And the Collection or Request Pre-Request Script Tab:

Postman Script Before

And in the Authentication Tab (note the double braces):

Postman Variable Usage

Now we can launch the Collection and know that the authentication token will be acquired as well, without having to remember to do it manually.

This is the first step towards our automation platform being truly useful. But before we do that, let’s add a couple more things to our Collection. We will add a test script that actually tests something. In my example Project, one of the outputs is the duration of the trip between the two stations. Let’s say that for whatever purpose, we consider a journey of greater than 20 minutes to be a functional failure. So we want to write an “after” script that looks at that for us. And let’s also say that we want to look at the response time and ensure that it meets our internal guidelines. So we might have a script like this:

function standardDeviation(values, avg) {
var squareDiffs = values.map(value => Math.pow(value - avg, 2));
return Math.sqrt(average(squareDiffs));
}

function average(data) {
return data.reduce((sum, value)=>sum + value) / data.length;
}

if (responseCode.code === 200 || responseCode.code === 201) {
response_array = globals['response_times'] ? JSON.parse(globals['response_times']) : []
response_array.push(responseTime)
postman.setGlobalVariable("response_times", JSON.stringify(response_array))

response_average = average(response_array);
postman.setGlobalVariable('response_average', response_average)

response_std = standardDeviation(response_array, response_average)
postman.setGlobalVariable('response_std', response_std)
}

This script uses three global variables that you create in the same way as environment variables and one of them is an array, representing the different times you run your request for example. In pictures:

Add an “after” Test Script:

Add the Variables :

Run the Collection or Script and observe the variables are evolving:

And let’s add another test, this time to check the journey duration is not too long (paste this after or before the existing “after script).

As you can see above, you are able to access the output of the request using JSON and then you can pose a condition. In the example above, the test has failed because I chose two stations that are very far apart. This is getting rather interesting. The next part is to use some data that makes our requests a bit more useful and to automate them. See you soon  for the next part!

Kudos to the following pages :

How to Automate OAuth2 in Postman

A Postman script to calculate average response times

Input Validation in an Input Extension – IBAN Validation

Input Validation in an Input Extension – IBAN Validation

A funny thing happened today – I came across a forum post that was talking about exactly what we had been describing to someone else the same day. Odd. These confinement measures play tricks with your mind. Anyway here is the scenario, it’s about input validation.

The customer needs to validate a banking account number in IBAN format in Oracle Policy Automation as part of an HTML Interview. What are the options for input validation?

There are several ways to handle this

  1. If you are just validating one country-origin IBAN numbers then you could certainly use Regular Expressions on your Input Text Attribute. A checksum rule would provide extra validation.
  2. Write a lot of Error or Warning Rules to achieve the same.
  3. But given there are many formats and many countries, if you need something bigger then you had better use some help!

There are standalone JavaScript libraries like this one, or you might use the jQuery Validator instead. It comes with IBAN validation as part of the additional methods supplied with it.  Since a lot of people are familiar with jQuery, and since Oracle Policy Modeling already uses it, we decided to opt for that solution for input validation.

We downloaded the validator and the additional files. we ensured that jQuery was accessible to the Project (in short, we clicked the Styles button in the Interview, then the Custom.. button and said OK before pasting the files in the folder). If this was a real-life case we would load the files in the correct order programmatically (jQuery, Validator, then additional stuff) but for this quick hack we renamed the files in alphabetical order to make sure they loaded like A, B and C.

We created an Input attribute, and named it something like this:

Input Validation - Create Attribute

Then we added it to the Screen and hooked up a custom property to make sure the code is executed for the IBAN element.

Input Validation Setup Screen

Then I fired up my trusty Code Generator and created a template Input Extension. I edited the Validate handler and this is the complete input extension. Of course this is the bare bones but it will do for a start :

//*  Generated by the OPA Hub Website 18/03/2020 08:06
Educational Example of Custom Input Extension for Oracle Policy Automation
I will remember this is for demonstration purposes only.
 */
OraclePolicyAutomation.AddExtension({
	customInput: function (control, interview) {
		if (control.getProperty("name") == "xIBAN") {
			return {
				mount: function (el) {
					console.log("Starting name:xIBAN customInput Mount");
					var div = document.createElement("input");
					div.id = "xIBAN";
					div.value = control.getValue();
					div.setAttribute("data-rule-iban", "true");
					el.appendChild(div);
					console.log("Ending name:xIBAN customInput Mount");
				},
				update: function (el) {
					console.log("Starting name:xIBAN customInput Update");
					console.log("Ending name:xIBANcustomInput Update");
				},
				validate: function (el) {
					console.log("Starting name:xIBAN customInput Validate");
					//errorplacement ensures the standard message is not visible
					var validator = $(".opa-interview").validate({
							errorPlacement: function (error, element) {
								return true;
							}
						});
					var returnvalue = validator.element("#xIBAN")
					if (returnvalue === true) {
						control.setValue(document.getElementById("xIBAN").value);
						return true;
					} else {
						return 'Your Message Here - THIS IS NOT A VALID IBAN'
					}
					console.log("Ending name:xIBAN customInput Validate");
				},
				unmount: function (el) {
					if (control.getProperty("name") == "xIBAN") {
						console.log("Starting name:xIBAN customInput UnMount");
						var xIBAN = document.getElementById("xIBAN");
						xIBAN.parentNode.removeChild(xIBAN);
						console.log("Ending name:xIBAN customInput UnMount");
					}
				}
			}
		}
	}
})

Input Validation

Input Extension – Summary

The basic idea is simple – when the Validate handler fires, pull the form and the input element and validate it as an IBAN number. If it passes, then there is no error message. Otherwise the validate fails and you can tell the user. You can have a more interesting message than this of course.

The Zip Archive is in the OPA Hub Shop. Have fun!

Continuous Development – OPA and Postman, Newman and Jenkins #1

Continuous Development – OPA and Postman, Newman and Jenkins #1

For the first time in a while I was working to set up an example platform for testing purposes. Whilst a good portion of it is not specific to Oracle Policy Automation / Intelligent Advisor, it seemed both useful and appropriate to document some of the ideas, steps and conversation points in some posts here on the website. So without further ado, let’s get started. In this series we will look at setting up Oracle Policy Automation, Postman, Postman Runner, Newman and Jenkins to enable lights-out testing of batch or XML-based projects. Then, once we’ve done that, we will extend our reach to include HTML Interviews.

Firstly, let’s get a handle on the different tools in the kit. Postman, as many will know, is a visual client for testing REST APIs – at least that is what people know it for – but it is in fact capable of making any kind of HTTP call. Although the examples here will focus on the Oracle Policy Automation Batch API, you could use it for SOAP Assess as well.

Learn About Postman

Download Postman for Windows, iOS or Linux

To make a call to an Oracle Policy Automation Project, here are the prerequisites

  • The Project needs to be deployed
  • You need to have an API Client user and password
  • You need to be able to build a sample case.

So, let’s get started!

Assuming you have an Oracle Policy Automation Hub at your disposal, or someone who can sort you out with access to one, then you need to start with the creation of an account of type “API Client”. You will need to be given access to the determinations API, for at least the Collection (or “workspace” as it is now known) and then the account needs to be activated. It probably will look something like this:

Create User for Postman

  1. Go to Permissions > API clients
  2. Create a user and enable them
  3. Select at least the workspace where your project is deployed
  4. Save the user

Your project will need to be deployed in web service mode (not Interview mode, but if it is also used as an interview that’s fine too.

Check Project Deployed

 

So now you are ready to fire up Postman and get this show on the road. Remember that when using the REST api for determinations, you are going to be using OAuth2 as your authentication mechanism. This requires you to make a call first to an authentication URL, and receive a token. That token is valid for 1800 seconds, and must accompany any calls you make to your project. So, here is what you need to do in Postman:

Create a Collection. To keep things organized in Postman, put stuff in a Collection. Create one, give it a good name and then later you can put all your different Requests to OPA in this Collection.

Postman Collection OK

 

While creating your collection, you can set up the Authentication as well. This way, any Request you make that is stored in this collection can inherit the authentication method you define. It’s easier than doing it for every request (although that is also possible).

Postman Authentication Start

Select OAuth 2.0, Request Headers and then click the Get New Access Token button. Since this is the first time you have done this, you will now be tasked with filling in a detailed dialogue to explain to Postman how to go and get the magic “token” for Oracle Policy Automation. The screenshot is accompanied by comments below for each of the steps.

  1. Give the Access Token Authentication a name. You might have multiple Hubs and need to have different data for each of them, so a name is a good thing.
  2. Select Client Credentials
  3. Enter the address of the authentication endpoint. This is something like the address above (replace “http://localhost:7777/opa19d/” with your own URL to your Hub. Note that recently the Authentication URL has evolved, and it is now versioned. Check your version of the documentation to see if you can use the new URL format (“api/version/auth”) and gradually migrate all your calls to this new format, even if the old format works for now (this was introduced in version 20A).
  4. Enter the API Client you created or decided to use
  5. Enter the password you set up.
  6. Select Send client credentials in body
  7. Click Request Token

If everything went according to plan, you should see this:

Postman Authentication OK

Obviously, click Use Token. You are now ready for showtime. You have 1800 seconds to get your first request into Oracle Policy Automation!

Finish your Collection creation (we will be using the other features of the Collection later, in the other parts of this story). Create a new Request and save it in the Collection.

Let’s assume you have a Project ready to go. If you don’t the project I’m using in this demo can be downloaded here. The Body of the request (using Raw JSON as your format) would look something like this:

{ "outcomes": [
"b_success",
"resultstepnumber",
"resultstep",
"totaltime"
],
"cases": [
{
"@id": "1",
"origin": "Miromesnil",
"destination": "Oberkampf"
},
{
"@id": "2",
"origin": "Grands Boulevards",
"destination": "Concorde"
}
]
}

This assumes your project has a boolean to indicate success and some other attributes (in my case, the step number, the step and the total time. This project calculates the time to travel between two Paris Metro stations, in the days before confinement and lockdown. There are two cases to be tested. They are based on two attributes, namely origin and destination.

The output should look something like this:

{
"cases": [
{
"@id": "1",
"b_success": true,
"totaltime": 42,
"theresults": [
{
"@id": 0,
"resultstep": "Miromesnil",
"resultstepnumber": 1
},
{
"@id": 1,
"resultstep": "Saint Augustin",
"resultstepnumber": 2
},
{
"@id": 2,
"resultstep": "Havre Caumartin",
"resultstepnumber": 3
},
{
"@id": 3,
"resultstep": "Auber",
"resultstepnumber": 4
},
{
"@id": 4,
"resultstep": "Opéra",
"resultstepnumber": 5
},
{
"@id": 5,
"resultstep": "Richelieu Drouot",
"resultstepnumber": 6
},
{
"@id": 6,
"resultstep": "Grands Boulevards",
"resultstepnumber": 7
},
{
"@id": 7,
"resultstep": "Bonne Nouvelle",
"resultstepnumber": 8
},
{
"@id": 8,
"resultstep": "Strasbourg Saint-Denis",
"resultstepnumber": 9
},
{
"@id": 9,
"resultstep": "Réaumur Sébastopol",
"resultstepnumber": 10
},
{
"@id": 10,
"resultstep": "Arts et Métiers",
"resultstepnumber": 11
},
{
"@id": 11,
"resultstep": "Temple",
"resultstepnumber": 12
},
{
"@id": 12,
"resultstep": "République",
"resultstepnumber": 13
},
{
"@id": 13,
"resultstep": "Oberkampf",
"resultstepnumber": 14
}
]
},
{
"@id": "2",
"b_success": true,
"totaltime": 12,
"theresults": [
{
"@id": 0,
"resultstep": "Grands Boulevards",
"resultstepnumber": 1
},
{
"@id": 1,
"resultstep": "Richelieu Drouot",
"resultstepnumber": 2
},
{
"@id": 2,
"resultstep": "Opéra",
"resultstepnumber": 3
},
{
"@id": 3,
"resultstep": "Pyramides",
"resultstepnumber": 4
},
{
"@id": 4,
"resultstep": "Madeleine",
"resultstepnumber": 5
},
{
"@id": 5,
"resultstep": "Concorde",
"resultstepnumber": 6
}
]
}
],
"summary": {
"casesRead": 2,
"casesProcessed": 2,
"casesIgnored": 0,
"processorDurationSec": 0.04,
"processorCasesPerSec": 45.45
}

For the sake of space, I’ve cut this off before the end. But you should be getting the idea. The output is the time taken, and the steps from the origin to the destination. There are some stations on my map which are inaccessible (because I didn’t fill in the entire map of the Paris Metro) so the boolean tells me if the route is possible, and the total time is also shown. Now that we have the basic setup, in the next part we will add

  • A test script to calculate average response time
  • A test to see if the route is possible
  • A command line to be able to run this without Postman

See you in the next part!

Winner 2019

Winners – Where Are You?

Winners – Where Are You?

We appreciate that you have many more important things to think about right now, but we just wanted to remind our recent winners that we are still waiting to receive address information so we can send some wearable goodies. If you want to find out what they look like, then you only have to see what winner Orlando R, sent the OPA Hub Website earlier this month.

Orlando R. is a long time Oracle Policy Automation / Intelligent Advisor practitioner, and we have had the pleasure of crossing paths with him multiple times over the last 15 years or so, from his early years in the Siebel CRM world, to his fanatical use of Oracle Policy Automation today. He is a very respected member of the community and an all-round nice guy as well.

Winners 2019

Here you can see Orlando, one of the winners, modeling his fantastic tee-shirt and winner’s mug. He also, of course, received a copy of the new JavaScript Extensions book in electronic format.

So, Annie and Manohar, please reach out either in the comments here or (better, since you probably don’t want to print your address in the comments) via LinkedIn. We look forward to sending you the prizes.

And it is worth saying, the OPA Hub Website wishes all of our readers and their families the best of everything during these difficult times, wherever you are in the world. As someone who spends nearly 150 days away from home on average each year, it is safe to say that it is a time for adjustment and new opportunities, as well as a time for protecting and nurturing those that I love and cherish. May we all come out of this in a better place than before.

We will continue to post during these times. Have a great day. And if you have not yet participated in the survey, please do.

Whats New in Oracle Intelligent Advisor 20A?

Whats New in Oracle Intelligent Advisor 20A?

The crop of new features in 20A this month can also be filled out with some extra new features that crept into 19D when it was updated about a month after the initial release.

20A General Release

In 20A, the focus is very much on enhancing the connection with Oracle Engagement Cloud. As those who work with it know, up until now getting set up with an Intelligent Advisor interview has required Groovy Script. More importantly, Oracle Engagement Cloud / Oracle Intelligent Advisor integration has lagged behind the others (notably the Oracle Service Cloud, or even Oracle Siebel integrations) in terms of functionality. And finally, in the past it was absolutely awful in performance terms, notably the GetMetaData was renowned, at least where I was working, for taking up to 4 minutes to provide a response.

The performance issues were worked on a while ago, and Oracle have made great strides in that direction, so now it is fantastic to see that the other aspects of the connector are getting some love too:

Dynamic reference data loading – the ability to load in additional data from Engagement Cloud (for example, product catalog or transaction history information) after the user is already part way through an advice experience, Yup, ExecuteQuery comes to Engagement Cloud integrations.

Native Intelligent Advisor control in Application Composer – adding an Intelligent Advisor interview into a subtab of an agent workspace no longer requires groovy script. Essentially a “plug and play” drop-in component for your Oracle Engagement Cloud subtab.  You can read more about it here.

Connector support for the Case object – Given the broad reach of Oracle Intelligent Advisor (benefits, law enforcement and so on) in the Public Sector and other “case focused” industry use cases, Case records can now be loaded, updated and created directly from Intelligent Advisor interviews. This includes support for  child objects of case (contact, household, message, resource and custom child) within the same interview. For further details, you can click here.

As a final, fun bonus – this time not related to Oracle Engagement Cloud – Image Control Extensions come to JavaScript! Very cool, since I have a friend and customer who has been waiting for this for a long time. Thanks to Oracle Intelligent Advisor Development for delivering it. We’ll be showing an example in the coming days. You get stuff like this:

  • getImageSource() – Returns the URL of the image to be displayed
  • getLinkUrl() – (Optional) Returns the URL of the link the user should be navigated to when they click on the image
  • openLinkInNewWindow() – Returns true if the image’s link URL should be opened in a new window
  • getHorizontalAlignment() – Specifies the horizontal alignment of the control
  • getWidth() – Returns the width of the control in pixels
  • getHeight() – Returns the height of the control in pixels
  • getCaption() – Returns the image description (alternate text)

If you want to learn about Control Extensions, you can read the book.

There are a few other enhancements, notably a versioned authentication in REST. But the OIA team have once again moved the bar higher and I think they deserve a big round of applause.

Community Post – Dynamic Options

Community Post – Dynamic Options

It’s always a pleasure to receive article submissions from the OPA Hub Website community, so this week I am pleased to relate to you an article suggested (and indeed documented) by Jeff Gwilliams, from Australia. His example shows how to create Dynamic Options. If you would like the Zip File, just leave a comment!

Jeff, as do all good Oracle Policy Automation (OAI) consultants, carefully measures the need for any requested functionality to see if it can be achieved by using a combination of out of the box tools. If, and only if, it cannot, then Extensions may be the answer. But, as the saying goes, the best piece of code is the one you don’t write.

So it is in that spirit that Jeff provides us with an excellent example of delivering some dynamic display of options, with no JavaScript required. His example is as follows. In this short demonstration, it uses the simplest expression of all the requirements, so there are no entities or inferred instances which could also be used.

The Setup

A user must be able to enter one or more contact methods (email, home phone, cell phone and so on). Then, they must choose their preferred contact method. So, if they can enter 5 different methods, but they only provide two, then the “preferred contact method” should only show two. And, for extra bonus points, the choices should show the actual number or email address that the user entered. As often, a picture will show it more clearly.

Dynamic Options

Of course, there should be no radio buttons if you only have one Contact Method, since there would be no option! Here’s how Jeff put it together

  1. Set up the attributes for the basic layout shown above

Set up visibility rules for the different preferred contact options – so that the radio buttons will not show if you have not entered anything (these are just two of them, you get the idea):

Dynamic Options

Set up rules to understand how many items the user has entered (again these are just a couple, you get the idea):

Now comes the smart stuff: he creates a Value List which uses the %attribute_name% format for the actual display. You probably already know that this format is used for substituting in Forms and Screens (and, as we mentioned a while ago, in Error() and Warning() rules as well). So the radio buttons will display the values entered by the user.

Dynamic Options - Value List

Then having set this Value List is the source for his attribute “the preferred contact option”, he applies his visibility rules to the values on the Screen:

So now his preferred options are shown only when needed, and they display the correct values. Nice job, Jeff!

We encourage you to submit your own articles and we will be happy to reproduce them here. What tricks do you have to share with the community?

Have a nice day!

OPA Hub Quiz Winner

Prize Quiz Open Again – Try your Luck!

Prize Quiz Open Now – Try your Luck!

For those of you who fancy winning a nice set of prizes, the OPA Hub Website Prize Quiz has opened up again for new entrants. It’s extraordinarily humbling to see that since we introduced them, over 1,200 quizzes have been taken.

To help you get in shape for the prize quiz, we are releasing over the next few weeks another 3 short quizzes, which give you the feel of the prize quiz without the stress. And to further incite you to try your luck, we have reset the leaderboard on all the quizzes. So if you are quick you might be top of the leaderboard for a while!

To keep everyone on their toes, the prize quiz has also been updated and now has more questions, some of which are, really quite hard. But they should be fun as an intellectual exercise. Here are some of the prizes that are on offer this time. As well as copies of the JavaScript Extensions for Oracle Policy Modeling book, we have our limited edition mug with our mascot celebrating your OPA Hub Quiz victory.

OPA Hub Quiz Winner

In addition, we will be giving away a an OPA Hub Cap:

OPA Hub Quiz Cap

The results of this round of the quiz will be published on May 31st, 2020, so you have a few weeks to get ready for it.  Just to keep you on your toes, we will be adding further questions to the quiz during the competition period – so if you take it twice, you would not have the same questions in each Quiz. In the meantime of course you can also get some practice by trying our quick and easy quizzes that you will find in the menu above, under (surprise surprise) Quizzes.

It’s only left to us to wish you good luck in the competition, and to ask you if you have ideas for further quizzes, then please reach out!

Dynamic Images in Forms

Dynamic Images in Forms

I had an interesting exchange about this subject on another forum, so I thought I would reproduce it here in another slightly more structured format. The question revolves around the following requirement :

  • In an Oracle Policy Automation project, display a dynamic image – for example, a chart derived from dynamic data such as a D3.js visualisation.
  • From that dynamic chart, get a bitmap copy of the D3 chart
  • Push that image into a Form using BI Publisher.

For the sake of simplicity let’s assume that you are using Word RTF as your basis, although it should also work in PDF templates.

What is the shopping list we need for a prototype dynamic images in Forms:

  1. D3 chart content (as an SVG) can be dynamically displayed (something like the attached sample project)
  2. Get hold of the SVG from D3 and redraw it on a Canvas
  3.  Now convert the Canvas to JPG
  4. The JPG can be served up to BI Publisher using Base64 encoding

In short order, therefore:

We can get the D3 SVG and copy it onto a canvas element :

function paintSvgToCanvas() {
var pbx = document.getElementById("pbx");  //this is the image that will be displaying the SVG copied from D3
var uCanvas = document.getElementById("mycanvas"); // this is the HTML canvas
var uSvg = document.getElementById("mySVG"); // this the D3 SVG
pbx.src = 'data:image/svg+xml;base64;utf-8,' + btoa(unescape(encodeURIComponent(uSvg.outerHTML)));
uCanvas.getContext('2d').drawImage(pbx, uCanvas.width / 2 - pbx.width / 2, uCanvas.height / 2 - pbx.height / 2);

// Now we have a canvas, with the SVG on it

}

In the second step, we can get that SVG on our canvas and turn it into a bitmap:

var imgInitial = canvasTag.toDataURL("image/jpg");
var imgFinal = img2.replace(/^data:image\/(png|jpg);base64,/, ""); // strip off the header, not needed for BI Publisher
var finalImage = document.createElement("img");
finalimage.setAttribute("width", "800");
finalimage.setAttribute("height", "470");
finalimage.setAttribute("id", "finalimage");
finalimage.src = imgInitial ; // display the image using the full toDataURL
document.body.appendChild(finalimage);

interview.setInputValue("myimage", imgFinal ) // push the toDataURL less the header into an attribute for BI Publisher

Finally, in BI Publisher, ensure that you use the same tag structure as the Signature feature to ensure the image is correctly handled:

<fo:instream-foreign-object content-type="image/png" xdofo:alt="An Image" ><?myimage_value?></fo:instream-foreign-object>

And it works. Of course it really should work, since the underlying mechanism is used out of the box to allow signatures to be printed in BI Publisher Forms :

But the as yet immovable issue, is that Text attributes are limited to 32,767 characters, so the dynamic images in Base64 better be simple ones, or we run out of space.  There are a couple of potential workarounds none of which is very appealing – somehow splitting the image across multiple entity instances and concatenating them in BI Publisher code (ugh). Compression is not an option since Base64 compresses so poorly, which is an interesting discussion in itself.

Have fun with some not-too-big images!

Thoughts on Installing OPA 19D On Premise

Thoughts on Installing OPA 19D On Premise

I addressed these thoughts in another forum, but figured I might put them here too, but under a different angle. Recently I discovered, as you do, that the installer for the On Premise Server Components of Oracle Intelligent Advisor 19D (aka Oracle Policy Automation Server Components) had a bit of an issue. As you probably know, it comes with three options (there used to be a fourth I think, in the 2014 timeframe, when the In Memory Analysis Server thing was being introduced).

Installing 19D

You can see them in the top part of the screenshot above, and you can see my issue in the lower section. the installer just dumped me out without any warning, complaining that I hadn’t given the deployment a name. Well I had not had a chance to even think about it because the script crashed as soon as I hit Return. Now, the java magic behind this script has been reverted to “Update 1” rather than “Update 2” according to the excellent response I got from Oracle. But that is not the purpose of this post.

In spite of the error above, and the errors in the other two options which stopped me from doing anything at all  – the second option had the same problem:

And the third option couldn’t work without the database and randomize seed key being present. So I was stuck. This was just a test machine, so I was not under life or death pressure, but I didn’t want to give up as I had to do some work on 19D. So after checking everything was versioned correctly and installed (WebLogic 12c was already running and healthy, Java JDK and JRE installed and in the path, that sort of thing) we decided to do it manually.

The On Premise installation of Oracle Policy Automation can broadly be defined as three steps

  • Create the user and database
  • Populate the database with the tables
  • Populate the tables with the seed data (such as the user admin)

These can be done manually by a combination of the following :

  1. Reading and following the On Premise guide where it provides helpful examples of the creation of the OPA Hub database user. There is little more to do that make any changes to the password or username and just run it.
  2. Running the SQL Script in the /unzippedinstaller/opa/bin/sql folder that creates the database (“create_tables_oracle.sql”). Again, aside from making sure you are connected with the user you just created, just click and go.
  3. Running the SQL Script which injects the seed data (such as the admin user and the basic roles, configuration settings and so forth) which is in the private_cloud subdirectory and is called “seed_data_oracle.sql”.
  4. The final step is to reset the admin password for the future OPA Hub. This uses the admin command (the admin.sh or admin.cmd is present in the unzipped folders in the same location as install.cmd) with the -resetpassword switch. The various options are detailed in the documentation, if you are using Oracle DB don’t forget to use both the dbconn as well as the dbtype and dbuser and dbpass options. If you get a message about admin not being a user, go into the authentication_pwd table (there should only be one record) and change the status flag from 1 to 0 or vice-versa. Commit the changes then run the admin script again with your new password request.
  5. You can now run the third option to create the web applications and manually install them on the WebLogic server using the Deployment option. Don’t forget to create a Data Source pointing to your database before you install (it is documented here). On a test server I always put it as the default datasource as well to save me time.

Now you should have an up and running OPA 19D :

19D Welcome Screen

There are of course a number of other things you might have to fiddle with or that you can leverage. In my case, there was already a 19D database instance installed some days previously using the original installer, so a clone might have been an easier option.

Now let’s just make something clear. Under no circumstances am I telling you to do this. I’m putting this here because I thought it was interesting and educational. But you must the installation tools and guide provided. I will not be held responsible for anything or anyone.