Archive for November, 2015

ADF BC REST Services–II – Change Indicator

In ADF, often we see error saying ‘JBO-25014: Another user has changed the row with primary key oracle.jbo.Key’. The framework throws this error to make sure that none of the user changes are accidentally overwritten by another user and generally occurs when a user trying to modify record that has been just modified and committed by another user. In this post, we will see how to take care of this scenario using ADF BC REST services in context of HTTP PATCH.

ADF BC REST Services make use of attribute called changeIndicator  which can be observed in response of GET.

Follow the steps mentioned below to enable this in a resource:

  • EO should have an attribute marked as Change Indicator and set Track Change History as shown below.

ovn

  • Add this attribute in VO i.e to be exposed as REST resource.

ovnvo

Deploy your changes and issue GET to observe changeIndicator as below.

get

cin

for e.g. changeIndicator for department 10 (resource instance):

ACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D0300014900047
3697A65787000000001770400000001737200116A6176612E6C616E672E496E746567657212E2A0A4F7
81873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08
B02000078700000000178

Now update department 10 using following sql query to simulate the actual update.

update departments set department_name = ‘Administration-modified’, object_version_number = object_version_number+1
where department_id = 10

Issue GET again on same resource and observe the changeIndicator.

ACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D0300014900047
3697A65787000000001770400000001737200116A6176612E6C616E672E496E746567657212E2A0A4F7
81873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08
B02000078700000000378

 

cin1

As observed above, the value of changeIndicator changes with each update and is calculated by RESTServlet registered in web.xml of RESTWebService project.

restsvlt

Here is an interesting observation and do issue issuing GET for department 10.

http://localhost:7001/departmentApi/rest/r1/departments/10

If we observe HTTP response headers, the value of ETag is same as that of changeIndicator. Hence changeIndicator works in similar lines of ETag defined in HTTP specification.

etag

Now let us observe the behavior of REST resource when  ETag is used for If-Match/If-None-Match HTTP headers during GET and PATCH. Basically these HTTP headers tells server to do requested operation when sent Etag value matches or did not match respectively.

Make sure you enclose ETag value with “ (double quotes) as shown below.

If-None-Match:

Using GET:

  • When resource is not modified, returns status code as 304.

getnonematch

  • When resource is modified, returns response with new changeIndicator value.

getnonematch1

Using PATCH:

  • When resource is not modified, returns response status code as 412.

patchnonematch

  • When the resource is not modified, then returns response with new changeIndicator value after update.

patchnonematch1

If-None-Match

Modified

Not Modified

GET

Status:200
(Query Successful)
Status: 304

PATCH

Status: 200
(Update Successful)
Status: 412

If-Match:

Using GET:

  • When resource is not modified, resource is returned.

getmatch1

  • When resource is modified, expected response status code is 304 but shows 200 with junk response.

getmatch3

Using PATCH:

  • When resource is not modified, returns response with new change Indicator value after update.

getmatch2

  • When resource is modified, expected response status code is 412 but shows 200 with junk response. However you will observe that the actual update is not happening though it returns 200.

patchmatch1

If-Match

Modified

Not Modified

GET

Status:304 Status:200
(Query Successful)

PATCH

Status:412 Status: 200
(Update Successful)

Note: As you observed above, ETag combination with If-Match header is not working as expected which is a bug in this release.

References:

http://docs.oracle.com/middleware/1221/adf/develop/GUID-589F3905-5A8D-402D-B2D2-3BEEB2D7DDD4.htm#ADFFD54158

Advertisement

ADF BC REST Services-I

In this blog post, We will see how to expose ADF VOs as REST resources. ADF has got native REST support in 12.2.1 release.

We will use Department, Employee VOs and following AM Data Model here.

vos

am

Creating Release Version:

Creating a release version in adf-config.xml is the first step to be done before exposing any of the AM VOs as resource. Use the following steps to create one and you can follow your own conventions for versioning REST resources. Here I  have given the initial version as r1.

relversion

rel1

relactive

Expose VO as REST resources:

Open AM and navigate to Web Service –> REST and Click + icon.

restampage

Creation of REST resources create a new project RESTWebService.jpr in our workspace that can be deployed as WAR through which these REST services get deployed.

restws

Give the resource name as shown below and click OK.

createrest

Observe the new RESTWebService project gets created.

restws1

Also observe other files related to REST resources that get created as shown below.

files

You can use the following tabs to choose the methods to be exposed and the attributes to be exposed to consumers.

attr

When a VO has View Links the Resource Structure will show all these VOs as shown below. Check these VOs as shown below if it has to be exposed as child resource.

restdetail

Deployment:

Modify context root of RESTWebService project as shown below representing the purpose of your REST API.

deptApi

Optionally, we can modify URL pattern in web.xml as shown below.

urlp

Integrated WLS:

Select RESTWebservice project and do Run on right click as shown below.

runintg

Standalone WLS:

Create EAR profile for ADF application and include RESTWebService project as shown below and deploy this EAR to standalone WLS.

ear

Once the deployment is done, you can access the REST resource using url like:

http://<<host>&gt;:<<port>>/<<ContextRoot>>/<<url pattern>>/<<version>>/<<resource name>>

For e.g.: http://localhost:7001/departmentApi/rest/r1/departments

We can also use latest keyword to access the latest version of the resource.

For e.g.: http://localhost:7001/departmentApi/rest/latest/departments

You can use any REST client to try out POST, DELETE, PUT, PATCH depending on the operations you exposed on REST resource.

Describing Resource – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/describe

Describing Resource Instance – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/10/describe

 

Querying Departments – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments

Querying a particular Department – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}

Creating Department – POST:

URI: http://localhost:7001/departmentApi/rest/r1/departments

Content-Type: application/vnd.oracle.adf.resourceitem+json

Body:

{
“DepartmentId”: 1000,
“DepartmentName”: “Administration”,
“ManagerId”: 200,
“LocationId”: 1700
}

Deleting a Department – DELETE:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}

Updating a Department – POST:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}

Content-Type: application/vnd.oracle.adf.resourceitem+json

X-HTTP-Method-Override: PATCH

Body: (contains only fields to be modified)

{
“DepartmentName”: “Administration-Modified”
}

Replacing a Department – PUT:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}

Content-Type: application/vnd.oracle.adf.resourceitem+json

Body: (Values not sent in body will be set to null)

{
“DepartmentId”:10,

“DepartmentName”: “Administration-Replace”,
“ManagerId”: 100
}

Querying Department for a few fields – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments?fields=DepartmentName,ManagerId

Querying a Department using an attribute – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}?q=DepartmentName=Administration

Querying a Department for only Data – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments?onlyData=true

Will not fetch any links or  metadata for resource instances in response.

Sorting Departments – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments?orderBy=DepartmentName:asc

URI: http://localhost:7001/departmentApi/rest/r1/departments?orderBy=DepartmentName: desc

Limiting the records in Querying Departments – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments?limit=2

Fetches only 2 records.

Querying Departments from a particular record– GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments?offset=2

Fetches only 2 records.

URI: http://localhost:7001/departmentApi/rest/r1/departments?offset=2&limit=5

Fetches 5 records starting from 2nd record.

Expanding a Child Resource – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments?expand=Employee (Child Resource Name)

Querying Child Resource – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}/child/Employee

Querying a particular Child Resource – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}/child/Employee/{Child Resource Id}

Querying a Child Resource using an attribute – GET:

URI: http://localhost:7001/departmentApi/rest/r1/departments/{id}/child/Employee?q=FirstName=Jennifer

References:

http://docs.oracle.com/middleware/1221/adf/develop/GUID-8F85F6FA-1A13-4111-BBDB-1195445CB630.htm#ADFFD589

http://docs.oracle.com/middleware/1221/adf/develop/GUID-589F3905-5A8D-402D-B2D2-3BEEB2D7DDD4.htm#ADFFD54082

MAF 2.1.2 to MAF 2.2 observations

Recently involved in activity of migrating MAF 2.1.2 application to MAF 2.2. Here in this blog post, I want to list down my quick observations of this. We have not used lot of advanced features of MAF in our application so the following list is not going to be exhaustive and at the same time, it will be different if you are doing migration from MAF 2.1.3.

  • Now the default Alta Skin version is 1.4, however we need to manually modify to this version in maf-config.xml for a migrated application.
  • AdfmfContainerUtilities.toggleSpringboard() APi is provided to toggle the spring board.
  • AdfmfJavaUtilities.getAdfELContext is deprecated and replaced by AdfmfJavaUtilities.getELContext.
  • The plugin-ids for core plugins Network Information, Camera and geo-location are changed to cordova-plugin-network-informationcordova-plugin-camera and cordova-plugin-geolocation respectively.
  • The options Include login server cookie in REST calls and Include basic authentication header in HTTP requests in Authorization tab of Login connection are no longer available.
  • Web Service Security Policies section came as new security section of maf-application.xml and we need to add OSWM policies oracle/http_cookie_client_ policy and oracle/wss_http_token_client_policy to imitate the 2 options listed above and this information is stored in new file wsm-assembly.xml found in .adf folder of application.
  • oracle/wss_http_token_client_policy policy is mandatory to be attached if you are making use of HTTP PATCH method in mobile application. This is one of the observations and may be required in another scenarios as well.
  • A new java.security file is added in resources/security folder containing security related properties where SSLv3 is disabled by default.
  • Android Back functionality is supported out of the box. The tag amx:systemActionBehavior can be used to override/add some functionality during back navigation.
  • We can achieve previous release back functionality using legacyBack tag in maf-config.xml.
  • Swipe  to Reveal design pattern is supported out of the box in ListView using amx:accessoryLayout.

I observed the following issues are resolved in MAF 2.2:

  • Now we can load multiple resource bundles in maf-feature.xml using loadBundle tag which was an issue in 2.1.2.
  • We can use the notation like #{resourceBundle[‘String.id’]} for labels and all in AMX pages. This was an issue in 2.1.2 because of ‘.’ in resource bundle key though it’s working from java code.
  • In 2.1.2, junk characters are shown in the response by RestServiceAdapter if the REST service returns an exception and is in Gzip format. This issue has been fixed in 2.2.

And I am still using a workaround for the following issues even after migrating to MAF 2.2:

  • Seeing inconsistency in behavior of Action property of command button/link. When throw AdfException is used in Action property binding code, the error is shown properly in android but not in iOS – Fixed in 2.2.1
  • When AdfmfJavaUtilities.overrideConnectionProperty is used to override ACS URL in connections, it’s not persisted on application relaunch, thus facing authorization issues – Fixed in 2.2.1

And I am still facing following new issues in MAF 2.2:

  • Range Change Listener with managed bean is not working for child collection in data control – Fixed in 2.2.1

Pages

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 379 other subscribers

Enter your email address to follow this blog and receive notifications of new posts by email.


%d bloggers like this: