From December 2018

Microservices and SODA: JSON Data Stored in an Oracle Database Accessed through​ REST or Java


Simple Oracle Document Access

SODA (Simple Oracle Document Access) is a non-SQL style of storing/retrieving JSON data in an Oracle database.

cold summer alcohol cocktail
Photo by Pixabay on Pexels.com

It’s so easy to work with SODA! Let’s get started.

First, enable ORDS schema in your database.

Second, deploy ORDS in K8s (you can also deploy ORDS standalone in your laptop or in a container if you don’t have one, here you can find an example).

Now let’s try it:

Create a collection:

A collection is a table that transparently stores JSON data for you. Execute the following instruction remarked in bold:

curl -i -X PUT http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON

HTTP/1.1 201 Created

Date: Sat, 22 Dec 2018 19:15:26 GMT

X-Frame-Options: SAMEORIGIN

Cache-Control: private,must-revalidate,max-age=0

Location: http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON/

Content-Length: 0

Insert JSON in the database:

Download this to a file called po.json and execute the following (please note the ID of the new doc created)

curl -X POST --data-binary @po.json -H "Content-Type: application/json" "http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON/"

{"items":[{"id":"1C0C85A9B7084DAD88AC9155DC998578","etag":"D17DBB877A3B846EDB32789589F8CDB791634359D615376D938D167AAA3E1F46","lastModified":"2018-12-22T19:21:02.243934Z","created":"2018-12-22T19:21:02.243934Z"}],"hasMore":false,"count":1}

Just in case you haven’t noticed the magic of this, take a look at the following picture:

sodajson.png

Retrieve document by ID:

The JSON data is stored in a table. Now we can retrieve the document by the ID that was previously given as follows:

curl -X GET http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON/1C0C85A9B7084DAD88AC9155DC998578

{"PONumber": 0,

"Reference": "ABANDA-20140803",

"Requestor": "Amit Banda",

...

"UPCCode": 85391181828},

"Quantity": 9.0}]

Search for documents:

So far, so good. But wait, there is more! Let’s search for the content of a JSON attribute, in this case, documents with PO number is 0:

curl -X POST --data-binary '{"PONumber":"0"}' -H "Content-Type: application/json" http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON?action=query

{"items":[{"id":"1C0C85A9B7084DAD88AC9155DC998578","etag":"D17DBB877A3B846EDB32789589F8CDB791634359D615376D938D167AAA3E1F46","lastModified":"2018-12-22T19:21:02.243934Z","created":"2018-12-22T19:21:02.243934Z","value":{"PONumber": 0,...]}}],"hasMore":false,"count":1}

Bulk insert:

Now, let’s insert a bunch of JSON’s, first download this content and save as POlist.json and execute the following in bold:

curl -X POST --data-binary @POlist.json -H "Content-Type: application/json" http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON?action=insert

{"items":[{"id":"0A6DF1E1A3A745D98DC3E3DD648732B2","...22T19:45:42.157916"}],"hasMore":false,"count":70,"itemsInserted":70}

As you can observe, we have inserted several objects with one shot.

Update a document:

Let’s update JSON with PO=0 we searched for before (take note of the ID):

curl -i -X PUT --data-binary '{"PONumber" : "99999"}' -H "Content-Type: application/json" http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON/1C0C85A9B7084DAD88AC9155DC998578

HTTP/1.1 200 OK

Date: Sat, 22 Dec 2018 19:55:10 GMT

X-Frame-Options: SAMEORIGIN

Cache-Control: no-cache,must-revalidate,no-store,max-age=0

ETag: BC9497081F1E314EE19DD777F2ED7E8425F51C21E7EC1968CEA8110A684C3F05

Last-Modified: Sat, 22 Dec 2018 19:55:10 GMT

Location: http://130.61.67.88:8080/ords/hr/soda/latest/shopcartJSON/1C0C85A9B7084DAD88AC9155DC998578

Content-Length: 0

 

List records, delete records and so forth:

And so on… Take a look at the SODA REST, Java and whitepaper documentation.

Discover more features

Take a look at the documentation on how to create more complex queries and many other features.

Last, but not least, notice that the JSON object can be different in each row, there is no constraint that forces to a specific structure.

Microservices and SODA

As you probably have noticed, SODA is nice for CRUD operations with JSON data (such as the list of products in the shopping cart) in the database. In addition, you can utilize a relational model for the rest of your app. In brief, SODA is good for building microservices for the modern applications of the digital era.

And finally, by storing your data in an Oracle database, you get benefit of it’s inherent robustness, reliability, resilience, high availability, fault tolerant, distributed (sharding), in-memory, backup/recovery and more.

ordsarch

That’s all folks!

Enjoy 😉

 

 

Enabling HR​ (or other) Schema for ORDS Oracle REST Data Services


Once we have configured ORDS, we must enable a schema for REST operations. Let’s do it for HR schema.

If the database doesn’t have the HR schema created, google for it or follow this doco.

Anyway, you can use the schema user you want.

And now let’s enable the schema, first, execute the following as SYS:

alter user hr grant connect through ords_public_user

And now, execute the following connected as the HR user:

DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_SCHEMA(p_enabled => TRUE,
p_schema => 'HR',
p_url_mapping_type => 'BASE_PATH',
p_url_mapping_pattern => 'hr',
p_auto_rest_auth => FALSE);
commit;
END;
/

And now we must enable database objects for REST operations:

DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_OBJECT(p_enabled => TRUE,
p_schema => 'HR',
p_object => 'EMPLOYEES',
p_object_type => 'TABLE',
p_object_alias => 'employees',
p_auto_rest_auth => false);
commit;
END;
/
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_OBJECT(p_enabled => TRUE,
p_schema => 'HR',
p_object => 'DEPARTMENTS',
p_object_type => 'TABLE',
p_object_alias => 'departments',
p_auto_rest_auth => false);
commit;
END;
/
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_OBJECT(p_enabled => TRUE,
p_schema => 'HR',
p_object => 'COUNTRIES',
p_object_type => 'TABLE',
p_object_alias => 'countries',
p_auto_rest_auth => false);
commit;
END;
/
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_OBJECT(p_enabled => TRUE,
p_schema => 'HR',
p_object => 'JOBS',
p_object_type => 'TABLE',
p_object_alias => 'jobs',
p_auto_rest_auth => false);
commit;
END;
/
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_OBJECT(p_enabled => TRUE,
p_schema => 'HR',
p_object => 'LOCATIONS',
p_object_type => 'TABLE',
p_object_alias => 'locations',
p_auto_rest_auth => false);
commit;
END;
/

Let’s try it:

curl -i -X GET http://130.61.67.88:8080/ords/hr/employees/198

{"employee_id":198,"first_name":"Donald","last_name":"OConnell","email":"DOCONNEL","phone_number":"650.507.9833","hire_date":"2007-06-21T00:00:00Z","job_id":"SH_CLERK","salary":2600,"commission_pct":null,"manager_id":124,"department_id":50,"links":[{"rel":"self","href":"http://130.61.67.88:8080/ords/hr/employees/198"},{"rel":"edit","href":"http://130.61.67.88:8080/ords/hr/employees/198"},{"rel":"describedby","href":"http://130.61.67.88:8080/ords/hr/metadata-catalog/employees/item"},{"rel":"collection","href":"http://130.61.67.88:8080/ords/hr/employees/"}]}

That’s all for the moment. Now we have the schema enabled, we can deploy ORDS as explained here, which allows working with REST operations from whatever consumer out there.

Enjoy 😉

 

Setup ORDS in a PDB


ORDS utilizes several schemas for working properly. Follow these steps just in case your database hasn’t been set up.

NOTE: you need DBA privileges as well as 2 tablespaces created before proceeding, ask your dba or get this info before starting (although you can also manage it on the fly if you have a few database skills…)

ords

In a machine with java configured and ords.war downloaded to a working directory issue the following command and provide the correct values when prompted:

java -jar ords.war setup
Enter the name of the database server [localhost]: (the IP or name of your database server or scan o vip or whatever such as 13x.x6y.x6y.xyz, ask your dba)
Enter the database listen port [1521]: (this is the default port...ask your dba)
Enter 1 to specify the database service name, or 2 to specify the database SID [1]:
Enter the database service name:(ask your dba, for exmaple orclpdb1.localdomain)
Enter 1 if you want to verify/install Oracle REST Data Services schema or 2 to skip this step [1]:
Enter the database password for ORDS_PUBLIC_USER:(a password provided by you, write it down, you'll need later...)
Confirm password:
Requires SYS AS SYSDBA to verify Oracle REST Data Services schema.

Enter the database password for SYS AS SYSDBA:(you must be a dba or lucky to have been given to you)
Confirm password:
Retrieving information.
Enter the default tablespace for ORDS_METADATA [SYSAUX]:( the name of an existing tblespace such as USERS, ask your dba)
Enter the temporary tablespace for ORDS_METADATA [TEMP]:
Enter the default tablespace for ORDS_PUBLIC_USER [SYSAUX]:USERS
Enter the temporary tablespace for ORDS_PUBLIC_USER [TEMP]:
Enter 1 if you want to use PL/SQL Gateway or 2 to skip this step.
If using Oracle Application Express or migrating from mod_plsql then you must enter 1 [1]:
Enter the PL/SQL Gateway database user name [APEX_PUBLIC_USER]:
Enter the database password for APEX_PUBLIC_USER:
Confirm password:
Enter 1 to specify passwords for Application Express RESTful Services database users (APEX_LISTENER, APEX_REST_PUBLIC_USER) or 2 to skip this step [1]:
Enter the database password for APEX_LISTENER:(a password provided by you, write it down, you'll need later...)
Confirm password:
Enter the database password for APEX_REST_PUBLIC_USER:(a password provided by you, write it down, you'll need later...)
Confirm password:
Dec 22, 2018 12:02:54 PM
INFO: reloaded pools: []
Installing Oracle REST Data Services version 18.3.0.r2701456
... Log file written to /Users/javiermugueta/ords_install_core_2018-12-22_120256_00476.log
... Verified database prerequisites
... Created Oracle REST Data Services schema
... Created Oracle REST Data Services proxy user
... Granted privileges to Oracle REST Data Services
... Created Oracle REST Data Services database objects
... Log file written to /Users/javiermugueta/ords_install_datamodel_2018-12-22_120538_00171.log
... Log file written to /Users/javiermugueta/ords_install_apex_2018-12-22_120551_00321.log
Completed installation for Oracle REST Data Services version 18.3.0.r2701456. Elapsed time: 00:03:08.81

That’s all!

Enjoy;-)

The Increasingly Important Role of API Management in the Adoption of Integrated SaaS Solutions Together with the Onprem and Third-party Systems


As the adoption of the cloud by companies progresses, we see how an ecosystem of cloud providers is being formed that must be integrated with each other and with the legacy systems of our customers. That is, it confirms what was already intuited, the cloud will be hybrid and multi-provider.

In this order of things it is necessary to incorporate mechanisms that help to govern the entire ecosystem.

This is not new, in the previous decade paradigms emerged to solve the integrations between the different systems that the companies were developing / implementing  mostly onprem. One of the failures that such practices unleashed was not adequately implement mechanisms for the government of the integrations between the different systems.

Nowadays, with the new paradigms of microservices, the concept of API management appears as a new attempt to bring order to the potential chaos that may end up happening if things are not done with common sense.

And it is certainly observed that it is more necessary than ever to adopt mechanisms that allow governing the wide range of APIs that are currently available for any purpose.

The management of APIs must cover the entire life cycle of the same, from its design to its withdrawal, through publication, securization and monitoring.

apimanagement
Oracle API Platform is Oracle’s offer to manage the life cycle of all APIs that a company publishes and consumes.

Oracle also provides a complete set of integration technologies and tools (data integration and ETLs, IoT, SOA, BPM, low code development…)

Enjoy 😉

Creating a Java Microservice with Helidon/Microservice Archetype Deployed in Kubernetes


helidon

With Helidon you can create Java microservices easily. In this blog, we are creating/exposing a REST service that gets a JSON document stored in an Oracle database and retrieves it to the requestor. For retrieving the JSON document from the database we are using ORDS and SODA but you can use JDBC as well, we’ll show it shortly in another post.

First, let’s create the project with the available archetype:

mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=io.helidon.archetypes -DarchetypeArtifactId=helidon-quickstart-se -DarchetypeVersion=0.10.5 -DgroupId=io.helidon.examples -DartifactId=quickstart-se -Dpackage=io.helidon.examples.quickstart.se

Modify the GreetService class for calling a backend service and the MainTest class removing the tests, you can find how it looks like here on GitHub.

Package the app:

mvn clean package

Now, start the app

java -jar target/quickstart-se.jar

And test the app locally, the app starts listening in 0.0.0.0:8080:

http://localhost:8080/greet

Now, let’s containerize the app with the Dockerfile included in the project:

docker build -t quickstart-se target

Run the container and test again:

docker run --rm -p 8080:8080 quickstart-se:latest

http://localhost:8080/greet

Now let’s deploy to Kubernetes:

First, we tag the container and then push it to the registry:

docker tag quickstart-se javiermugueta/quickstart-se

docker push javiermugueta/quickstart-se

Now let’s modify the deployment yaml to create a LoadBalancer and for pulling the image previously pushed in the registry:

... 
labels:

app: ${project.artifactId}

spec:

type: LoadBalancer

selector:
...

spec:

containers:

- name: ${proje
ct.artifactId}

image: javiermugueta/quickstart-se

imagePullPolicy: IfNotPresent

ports:

...

 

Let’s deploy the app to k8s:
kubectl create -f target/app.yaml
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
quickstart-se LoadBalancer 10.96.56.43 1xy.x1.x5.x24 8080:32243/TCP 2m
Take note of the public IP and test again:
javamicroservice
That’s all folks!!
Enjoy;-)

Weblogic Kubernetes operator or how to run WebLogic​ clusters in k8s


There are lots of WebLogic clusters running around the globe every day. When you withdraw money in the ATM, buy lettuces in the supermarket or make a phone call there is a WebLogic server (and probably an Oracle database too) is executing some logic for you.

Computing paradigms today tend to new standards and Kubernetes seems to be a big player for running workloads that need scalability, high availability, fault tolerant and resilience to disasters.

WebLogic was born in the 2000s with concepts such clusters, managed servers or nodemanager. Those entities were engineered for building robust software designed to run in the infrastructure utilized in the last years.

With the advent of the cloud, new paradigms and technologies arise, but things can’t be constantly rebuilt every time a new technology appears because of the cost of renewing it. The number of lines of  Java code written and compiled to run in WebLogic out there is huge, so is good for you to have the confidence that your current software will keep running and will allow you to modernize your applications progressively. The importance of having providers that guarantee the continuity of businesses goes beyond the technology trends or the latest fashioned cool software product launched yesterday.

For that reason, Oracle provides WebLogic-Kubernetes-Operator, a collection of artifacts that transparently translates the WebLogic architectural design concepts (AdminServer, managed server, NodeManager, …) to the Kunernetes concepts (pods, deployments, persistent volumes, replicasets,…) allowing to run WebLogic topologies in k8s transparently.

domain-architecture

With WebLogic-Kubernetes-Operator, Oracle provides a way for keeping safe the investments you have done so far and gives you time to face the future with tranquility.

Enjoy 😉

Deploy ORDS (Oracle Rest Data Services) to Kubernetes Cluster


ords

ORDS is a piece of software that acts as an intermediary between Oracle Database and the layers where business logic is implemented and/or consumed.

NOTE: If your database hasn’t been set up for ORDS just google for it or take a look at this post.

With ORDS you expose database objects as REST. ORDS can be started standalone or in an application server. Deploying ORDS in Kubernetes as stateless pods with several replicas provide an elastic layer of rest exposition, out of the database, with high availability and fault tolerant.

ordsarch.png

First of all, we need a container ready to run ORDS in standalone mode. For this particular case, we are utilising one already done, see yaml file mentioned in next steps.

kuberneteslogo

Let’s start creating a secret for storing the password for the user that makes de connection to the database:

kubectl create secret generic ordspassword --type=string --from-literal=password=[somepassword]
Now, take a look and download this yaml file here and make changes regarding the database connection service and floating IP (SCAN in the case of a RAC or host IP in case of a single instance).
        env:
        - name: DB_HOSTNAME
          value: "example:172.16.0.7"
        - name: DB_PORT
          value: "example:1521"
        - name: DB_SERVICENAME
          value: "example:jsonpdb.xxxxxx.yyyyyy.oraclevcn.com"
        - name: APEX_PUBLIC_USER_NAME
          value: "ORDS_PUBLIC_USER"
        - name: ORDS_PASS
          valueFrom:
After that, issue the following command:
kubectl apply -f my.yaml
That’s it, verify the service is available this way:
kubectl get svc
javiermugueta$ kubectl get svc

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

eciveci LoadBalancer 10.96.92.19 130.61.15.199 3000:31522/TCP 4d

kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15d

ordscontainer LoadBalancer 10.96.229.248 130.61.70.73 8080:31523/TCP 2d
Now check whatever URL that you may have enabled in the schema. For more info take a look here or here.
http://serviceip:serviceport/ords/hr/employees/
That’s all!
Enjoy 😉