Unplug a jar from Oracle REST Data Services

Oracle REST Data Services has a plugin programming model which allows for an incredible degree of extensibility in the product. The Getting Started guide provides a walk through of creating a plugin to add custom functionality. After developing the plugin, the key command to add it to ORDS is:

java -jar ords.war plugin built/plugin-demo.jar

From time to time, it may be necessary to remove the custom jar. There is not a specific command in ORDS to do that but there is an option with ZIP at the command line. In this case, the plugin-demo.jar is packaged in the ords.war at WEB-INF\lib so unplugging it is as simple as this on Windows:

zip -d ords.war WEB-INF\lib\plugin-demo.jar

On Linux or Mac, that would be:

zip -d ords.war WEB-INF/lib/plugin-demo.jar

It really is that easy.

Read only REST endpoints with ORDS

Getting access to data, and logic, in your Oracle database is made so very easy with Oracle REST Data Services (ORDS). With a few clicks you can REST-enable a table so that clients can query, insert, update and delete records in it. That’s all via REST requests and all without writing any custom SQL. Moreover, these REST services can be secured so that only users with the required role has access.

What if you wanted to provide open access to a subset of data without the overhead of authentication and role authorisation configuration? Consider an internal employee directory for example where employees, or other systems, in the organisation’s intranet can search for employees. Some Oracle customers have achieved this by creating a read only view and ORDS enabling that. There is another approach that does not involve ORDS enabling the schema where the data resides or creating views. Let’s explore that…

Context

In the scenarios outlined below there is database called ORCLPDB1 with a HR schema. ORDS is running on localhost:8080 and the URL for accessing the database is http://localhost:8080/ords/orclpdb1/

The example command line requests shown below uses HTTPie. You may be more familiar with curl, but HTTPie is worth exploring if you script REST calls because there’s less typing involved!

The HR application uses HR schema for managing employee details, contact information and sensitive information including salaries and bonuses. The EMPLOYEES table in the HR schema is the ultimate source of truth about the people employed in the organisation. It is only employee_id, first_name, last_name, email, phone_number, and manager_id that should be made available through a REST interface.

Which schema?

An ORDS Enabled schema is required because it will be with that user that queries on the HR.EMPLOYEES table will be performed in the database. One can ORDS Enable the HR schema or create a new schema which only exists to provide a REST interface and ORDS enable that.

In these examples we’re going to create a new schema called HR_REST and only give it the minimum of privileges required. You can call the schema whatever suits the nomenclature in your organisation. Some may consider HR_READ_ONLY or the shorter HR_RO names in this context.

Create schema

With a DBA or some other suitable privileged user, connect to the database and run the following:

CREATE USER HR_REST IDENTIFIED BY <password>;

GRANT CONNECT TO HR_REST ;
GRANT SELECT ON HR.EMPLOYEES TO HR_REST;

BEGIN
   ORDS_ADMIN.ENABLE_SCHEMA(p_schema => 'HR_REST');
END;

You will notice that the HR_REST can only CONNECT and SELECT so it is restricted at the database level as to what it can do.

Define Service

This is the point where we define a REST endpoint to retrieve just the columns required by taking advantage of the DEFINE_SERVICE procedure. Connect to the database as HR_REST user and run the following:

BEGIN
  ORDS.DEFINE_SERVICE(
            p_module_name => 'hr.read_only.employees',
            p_base_path => '/employees/',
            p_pattern => '.',
            p_source => 'select employee_id, first_name, last_name, email, phone_number, manager_id from hr.employees'
          );
  COMMIT;
END;

The employee list can now be accessed at http://localhost:8080/ords/orclpdb1/hr_rest/employees/ using GET.

http http://localhost:8080/ords/orclpdb1/hr_rest/employees/ 

HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 22 Mar 2019 18:14:04 GMT
ETag: "CfvOiafv+Tw6EyXoXwWPS8ZT8w0wkv0gHAy297hSqILBnV6OdzJ8MlTgngdhPuPv9p9MfsLCqSkyqmXiHedNlA=="
Transfer-Encoding: chunked

{
    "count": 25,
    "hasMore": true,
    "items": [
        {
            "email": "DOCONNEL",
            "employee_id": 198,
            "first_name": "Donald",
            "last_name": "OConnell",
            "manager_id": 124,
            "phone_number": "650.507.9833"
        },
...items removed for brevity...
        {
            "email": "DGRANT",
            "employee_id": 199,
            "first_name": "Douglas",
            "last_name": "Grant",
            "manager_id": 124,
            "phone_number": "650.507.9844"
        },
        {
            "email": "JWHALEN",
            "employee_id": 200,
            "first_name": "Jennifer",
            "last_name": "Whalen",
            "manager_id": 101,
            "phone_number": "515.123.4444"
        },
        {
            "email": "MHARTSTE",
            "employee_id": 201,
            "first_name": "Michael",
            "last_name": "Hartstein",
            "manager_id": 100,
            "phone_number": "515.123.5555"
        },
        {
            "email": "PFAY",
            "employee_id": 202,
            "first_name": "Pat",
            "last_name": "Fay",
            "manager_id": 201,
            "phone_number": "603.123.6666"
        }
    ],
    "limit": 25,
    "links": [
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/employees/",
            "rel": "self"
        },
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/metadata-catalog/employees/",
            "rel": "describedby"
        },
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/employees/",
            "rel": "first"
        },
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/employees/?offset=25",
            "rel": "next"
        }
    ],
    "offset": 0
}

Note the link to the metadata-catalog for the service. The one downside of this approach is that there’s no metadata about the structure of the response. If one had ORDS enabled a view, the metadata-catalog would at least describe the properties for each column.

However, the downside of ORDS enabling a view is that anything other than a GET will result in a HTTP 500 error response which is not ideal. The advantage of this DEFINE_SERVICE approach is that other HTTP methods will result in a very clear HTTP 405 Method Not Allowed response. For example:

http -v POST http://localhost:8080/ords/orclpdb1/hr_rest/employees/ first_name=Peter

HTTP/1.1 405 Method Not Allowed
Allow: GET
Content-Length: 15798
Content-Type: text/html

Similar to when a view is ORDS enabled, the ORDS pagination and query filter object query parameters can be used to find specific employees.

http http://localhost:8080/ords/orclpdb1/hr_rest/employees/ q=='{"first_name":"Alana"}'

HTTP/1.1 200 OK
Content-Type: application/json
ETag: "YNh9iZn3p5zFLO1zjlpaPtXBcdAGR3QMAatiPatERoTt5gievnW7Bz7qYFLNVP19H83pfE7rRRZiy0kRc5wXfg=="
Transfer-Encoding: chunked

{
    "count": 1,
    "hasMore": false,
    "items": [
        {
            "email": "AWALSH",
            "employee_id": 196,
            "first_name": "Alana",
            "last_name": "Walsh",
            "manager_id": 124,
            "phone_number": "650.507.9811"
        }
    ],
    "limit": 25,
    "links": [
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/employees/?q=%7B%22first_name%22:%22Alana%22%7D",
            "rel": "self"
        },
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/metadata-catalog/employees/",
            "rel": "describedby"
        },
        {
            "href": "http://localhost:8080/ords/orclpdb1/hr_rest/employees/?q=%7B%22first_name%22:%22Alana%22%7D",
            "rel": "first"
        }
    ],
    "offset": 0
}

Conclusion

By introducing another database schema, with restricted access just to the table required the level of exposure through the REST interface is reduced. While this could be achieved with a read only view, the response to clients that attempt to POST, PUT or DELETE is a HTTP 500 so it is much cleaner, and more RESTful one could argue, to use DEFINE_SERVICE in this case.

When machines learn to do what you do

For a brief time, I was a spy! On a clandestine mission, sending and receiving encrypted messages with my associates. That was for about 5 minutes and then I had to give someone else a go.

Exploring the city of spies @spionagemuseum

On a recent trip to Berlin I visited the German Spy Museum and spent hours upon hours enjoying the exhibits, the interactive displays, and learning so much about the history, and ingenuity of spy craft. One of the many interesting topics was the history of industrial espionage. From navigating to new worlds, metallurgy secrets and weaving cloth, the wealth to be gained was immense. There were clear advantages in these innovations that those who had them went to great lengths to protect what they had. Some others went to great lengths get a hold of it too.

One such innovation, was the automated weaving loom.

The history around the automation of the weaving loom was something I was already familiar with, particularly as Jacquard’s loom inspired Charles Babbage in early computational device design. The Jacquard Loom automated the work of weavers. Changing the punch cards changed the pattern, giving the weaver endless ways to “program” this device and to create intricate tapestries, damasks, brocades and other fabrics. What I did not know before writing this article was the difference between damask and brocade fabrics. Which goes to show that you can learn knew things. More on that later.

What’s the big deal about this automated loom then? Well, traditional silk weavers could produce approximately 2cm of complex fabric in a day. The skilled Jacquard Loom operator, however, could create approximately 50cm of fabric in the same amount of time.

The automated loom, which allowed for an incredible rise in cloth production, and more complex designs, was over 100 years in the making though. The challenges were not just technical. There was considerable opposition to machines destroying the livelihoods of weavers and those that worked in the weaving industry.

No doubt there were some who saw the attempts at automation in the mid 18th century and thought there was no way these clumsy, unreliable, and high maintenance contraptions would ever take the place of a human. Similar to how the Roomba of today does not put any cleaner in fear of replacement. Yet.

The topic of automation eliminating jobs is not a new one. For a many years some researchers and analysts have referred to the industrial revolution as the first machine age where automation changed the nature of repetitive manual work. Some consider us in a second machine age where it is not simply manual work being replaced. Research shows that there are worries about job automation globally.

A quick side note…the Washington Post review of The Second Machine Age, a book by two MIT professors who have coined the phrase, is exceptionally good. Much better than what I could have done, so I’ll link to that Washington Post review.

Back to the machines…What makes the industrial revolution significant over other periods of innovation is that before the first machine age, technological innovation resulted in larger populations, not wealthier populations. Take a look at those Our World In Data charts: https://ourworldindata.org/economic-growth

The real difference was on scale. Machines could make something that was prohibitively expensive, or time consuming, possible. A modern example would be the use of artificial intelligence to analyse sales calls which is what sales managers would do as part of developing their team. The good news is that one manager could potentially have a larger team. The bad news is that there may not be a need for so many managers.

Life long learning

A generation ago, the half-life of a skill was about 26 years, and that was the model for a career. Today, it’s four and half years and dropping

Indranil Roy – Future of Work

Looking back again at the weavers, those who continued in the industry became designers, putting an emphasis on the design and planning skills that were already apart of the weaver job description. They would also have learned the mechanics of the machines that was transforming their industry forever. This is a useful guide for how we should plan for more automation in our careers: constantly updating skills.

Which skills are worth updating though? Perhaps more importantly, how can one identify the skills that one has an ability for? Joseph E. Aoun suggests that there are three disciplines to consider: technical, data and human. These are effectively…

  • awareness and familiarity with the automation technologies emerging.
  • cognitive skills and data literacy so that more information-centric skills can be applied to understand the world around us and devise new strategies based on that understanding.
  • an understanding of creative practices and cultural experiences that develops the ability to take information from one context and apply it to another.

The technical and data abilities are perhaps the easiest to justify spending time and money on because the connection between them and work is much clearer. Deloitte’s Future of Work Centre of Excellence identifies these talents that are needed in the work place. These talents can help assess, and take advantage of, a process or level of quality that previously was too expensive, or impossible, until now. An employee dedicates a few hours a week to study digital marketing and before you know it, the business has a social media strategy.

However, the soft skills that are going to pay off are harder to identify, simply because of the human element. A passion for travel, baking, music or sports may not lead to a new career but can be very rewarding and by sharing that, may reveal new connections or opportunities. That digital marketing expert mentioned earlier may only have taken the initiative because of their interest in photography.

One of my favorite podcasts is NPR’s How I build this and here are just a few examples of people taking their interests, seeing that there’s a gap in the market, and doing more: SoulCycle, KickStarter, method, Drybar. The stories are inspirational but make it clear that even with planning, collaboration and support, success did not come easy.

You may be fortunate to have an employer that supports skill development, either by providing leave to study, or even a contribution to the cost of studying. Quite often the effort that goes into making the case to your employer for training is exactly the right measuring stick to gauge if this is something you really want to do. Perhaps you are not so fortunate and will have to cover the time and cost out of your own free time and pocket. If that’s the case, visit your local library or enterprise board because there may be grants or other schemes available to lessen the burden. Many OECD countries are coming around to be more proactive in supporting skills development in the workforce.

In summary, technological advances will make certain fields of expertise obsolete but will introduce new ones that we should prepare for. The best way to prepare is through learning new skills, but we do have to identify and choose the right ones. There are no easy answers to making that decision. That is, until someone comes up with an AI for exactly that purpose.

HDMI to VGA adapter comparisons

Is the new HDMI – VGA dongle form factor any good? Let’s find out and compare it with a few other adapters available.

Sonic Pi – http://sonic-pi.net/

Maplin adapter – http://www.maplin.ie/p/maplin-microministandard-hdmi-male-to-female-vga-adapter-n58nx
CAMAC adapter – http://www.amazon.co.uk/gp/product/B0088K7QVA
The Pi Hut adapter- http://thepihut.com/products/raspberry-pi-hdmi-to-vga-convertor