Quantcast
Channel: Practical experience on Oracle products
Viewing all 63 articles
Browse latest View live

Oracle Java and Database Cloud Services in Action

$
0
0

Yesterday the long awaited  Oracle Cloud became reality (at least for me)! Thanks Oracle! Of course I could not wait any longer and had to do a test drive with the Oracle Database and Java Cloud Services. In order to start we need the following

Getting started
Once you confirm your activation link for the trial request you will receive an email with Service Details for
  • Identity Domain (which actually is a logical group for associated Users and Cloud Services)
  • Oracle Database Cloud Service
  • Oracle Java Cloud Service
  • Domain FTPs Account Details
In the mail there also will be a temporary password which must be changed after first login at the Identity Console. One thing really overwhelmed me is the fact that for every service you get dedicated user credentials. So there is a lot of stuff that is to be handled.

Identity Domain / Console
The Identity Domain actually is a logical group for associated Users and Cloud Services that is managed by the Identity Domain Administrator. The Identity Console is a web based application for 
  • Manage  User Profile
  • Create / Delete Users, Reset Passwords
  • Create / Delete Roles, Assign to Users
The Identiy Console is build with ADF. It looks like that


Oracle Database Cloud Service 
The Oracle Database Cloud Service runs Oracle DB 11gR2 and is managed by Apex 4.1.1.00.23. So logically no ADF here. Imagine you are running Oracle XE. Same here.

RESTful Services (by Application Express Listener)
RESTful services are created inside Apex and are delivered right from the Database through the Apex Listener

The defined RESTful Services can be tested right from the browser:

As you can imagine this allows pretty rapid development of RESTful Services! Beside JSON, CSV Format is supported. No XML!


As a sample DB application the following Apex App is installed and by default to demo key features of Oracle Apex! Further Apex applications can be easily deployed from the apex Workspace.


DB Export
In order to export Database strucure + data it is possible to trigger a data pump job with a single Mouse Click. After the job is completed the Dumpfile can be grabbed through SFTP from the /download user directory. The created files are automatically cleaned up after about 2 days. So do not try to archive your data here.


My test worked well without any trouble! The download speed was acceptable to although I did not download Gigs of data.


Access DB Schema
Now let us come to the  interesting part. How can we access the DB Schema from - e.g. SQLDeveloper or JDeveloper. In this case I will demo it from the new JDeveloper 11.1.1.6 (Build 6229) 

In order to access the Database Cloud service from the IDE we need a so called "Cloud Connection User" to be created in the database service console (Apex) with the SQL Developer Group as stated in the JDeveloper context help. This can can be easily done through the Apex Admin Tools (Manage users and groups). I won't go into further details here.

Now it is possible to create the connection from JDeveloper/SQLDeveloper

Enter your service details


and we are up and running, being able to see the structure and contents of the cloud database instance. 

Access for example the table 'DEPT' and browse the data.
(The Tables EMP and DEPT are included in the cloud db schema)

The interesting part here is that it is not possible to change any database objects.

Deploying DB Objects is only possible through the newly introduced "Database Cart" which is accessible from "View > Database > Database Cart". 

That is a very new concept which needs a separate focus. More on that in a follow up post (Deploying Database Objects to Oracle Cloud using JDeveloper). Follow me on twitter to get updated in time (@multikoop)

Oracle Java Cloud Service Control
To monitor, deploy/undeploy start/stop Java and ADF Applications. It looks pretty simple and easy to use: Performance, Data Sources, Applications. Everything you need to get started.

This control is a subset of Oracle Enterprise Manager Cloud Control 12cR2 (12.1.0.2) as you can see in the about page.

In one of the next posts I am going to show how to "Deploying ADF Applications into the Oracle Cloud". Stay tuned.

Conclusion

In its current stage Oracle Cloud is promising Cloud Foundation for PaaS and SaaS. It includes
  • Identity Management / WebBased Identity Console (ADF Application)
  • Java Cloud Service Control to Monitor and Deploy your Java Applications (ADF Application)
  • Apex Control to Administer and Monitor Apex DB Applications and Cloud Connection Users
  • IDE Integration in JDeveloper 11.1.1.6 (Build 6229)
  • Oracle Cloud Java SDK Command Line Interface
  • IDE Integration in Oracle Enterprise Pack for Eclipse.
  • IDE Integration in Netbeans is on its way....
References

Start your cloud experience now! Goto http://cloud.oracle.com


Deploying Database Objects to Oracle Cloud using JDeveloper

$
0
0

As announced in my previous post I am going to show now how to deploy Database Objects from a "local" Database to the Oracle Database Cloud. For that showcase I am using the following environment

Environment
  • JDeveloper (JDEVADF_11.1.1.6.0CLOUD_GENERIC_121118.1600.6229)
  • Oracle XE Database 11gR2 with HR schema
  • Oracle Database Cloud Service
Goal
The primary goal is to deploy the tables HR.DEPARTMENTS and HR.EMPLOYEES into the Cloud Schema. So in a next step it will be possible to build an Apex or an ADF Application associated to these tables in the cloud.

Prepare DB Deployment
In order to use the tools provided in JDeveloper for seamless deployment of DB objects into the Oracle Cloud start JDeveloper and open the Database Navigator (View > Database > Database Navigator)

Now create an IDE DB connection to the desired database. I am using the well known HR schema on an Oracle XE DB. This is really straight forward. Just click "+" and add a Database Connection by providing the appropriate account details. Double Click on the created node connects to the database and explores its contents.


Next we need to connect to the Oracle Cloud Database Service. That is pretty simple too.

Enter your cloud service details


et voila, the cloud connection is established!


Important note: Before we go further let me explain the cloud connection details because this is really new and should be noted. The cloud connection actually has two channels. One for "read only" operations and another for DDL, and any SQLPlus scripts. That second channel works technically through SFTP and logically through the "Database Cart" where every db object or script is bundled into a ZIP for sending out to the cloud. Therefor you have to provide that information in the cloud connection wizard.

OK, so the last preparation step is to configure that "Database Cart". Goto: Tools > Preferences >Database > Utitlites > Cart > Cart Deploy and set the deploy directory according to you project needs.


Deploy DB Objects to the Cloud
After establishing the connections and configuring the Database Cart we are ready for deployment. Open Database Cart (View > Database > Database Cart) and Drag and Drop the DB Objects you want to deploy into the database cart.
Next: Click on Save

Click on Apply. 

The selected db objects (metadata) will be saved as an XML File. The Database Cart File contains Metadata about the database objects you want to deploy. To have a better understanding: it looks like that


It is kind of configuration file for the deployment of database objects into the oracle cloud.

Next Step is to deploy the selected DB objects + data into a ZIP file which afterwards will be used to transfer into Oracle Database Cloud.


The ZIP contains the corresponding scripts in order to deploy the objects and data some where else (cloud). Actually it contains a bunch of SQL scripts:


Now the last part is to deploy that ZIP file to Oracle Cloud.

Press Apply.

The data now is exported and transferred as a Deployment Unit on your Database Cloud Service.
You can verify your deployment by refreshing the cloud connection in JDeveloper

and also look into the processing log


The newly created Table DEPARTMENTS can be verified/viewed right from JDevelopers Cloud Connection



Once again - How does it work?
The chosen DB Objects + Data are exported from a database and put together in a deploy.zip file. By providing the SFTP DB Service Account details this file is transferred to the cloud through SFTP. You can verify this by logging into your SFTP Account:


To summarize
  • Configure Database Cart
  • Drag and Drop DB Objects into Database Cart
  • Deploy into Cloud
  • Verify Processing through Deployment Status/ Log
  • Verify deployed DB Objects through Cloud Connection right from the JDeveloper IDE
Having performed this steps next it is possible to build 
  • Apex Application
  • ADF / Java EE Application
  • RESTful Services
based on the deployed data structure. Stay tuned.

I really like that everything is bundled inside JDeveloper. No need to download any plugins or extra tools. Use JDeveloper to Build, Deploy DB and Java Applications (as I will show in the next post). Cool stuff! Goto cloud.oracle.com and try yourself!

Related Posts / Documentation


Deploying ADF Applications into the Oracle Cloud using JDeveloper

$
0
0

In this post I am going to show how to deploy Oracle ADF Applications into the Oracle Cloud using JDeveloper.

Prerequisites / Environment
You should have the following at your hands.
  • JDeveloper (JDEVADF_11.1.1.6.0CLOUD_GENERIC_121118.1600.6229)
  • Oracle Cloud Java Service (which includes the database cloud service as well)
  • Oracle Database (HR Schema)
  • Having deployed the DB Objects and Data (HR.EMPLOYEES and HR.DEPARTMENTS) as described in the previous post
Note: In its current stage Oracle Java Cloud Service runs WebLogic Server 10.3.6 with the appropriate Runtime ADF 11.1.1.6. Deployment of ADF 11gR2 Applications is currently not supported. Beside this limitation some ADF Features are not supported on the Oracle Cloud. According to the Oracle Cloud Documentation it is not supported to use the following ADF features
  • ADF Desktop Integration
  • ADF mBean
  • ADF MDS (Seeded customizations or cross-session personalization)
  • ADF Mobile
  • ADF Active Data Services (=> No real-time ADF Web Apps in Oracles Cloud)
  • ADF Business Components services interfaces (web services) or events
  • ADF Data Controls for BI, Essbase, BAM, and JMX
Further there are some restrictions which are good to know I think
  • No Java Mail API   (=>Sending Mails is prohibited)
  • No File system access by deployed applications (=>Writing files is prohibited)
  • No Direct use of Oracle JDBC Driver APIs
  • No Java Message Service (JMS)
  • Max Size for deployment archive 95MB

I wonder what 'ADF Mobile' in that context actually means. Mobile Browser Apps? Or the restriction that ADF Mobile Client apps cannot make use of ADF BC SDOs? Maybe someone from Oracle could comment. That would be great. Thx!

Setup ADF Application
OK, let's do the actual work. In order to have shown the whole deployment procedure (database objects and ADF Application) we are going to create a basic ADF Application that is running against a non-cloud, on-premise database first using the well known DB schema HR  - involving table EMPLOYEES and DEPARTMENTS. Remember that these table structure + data has been deployed to the Oracle Cloud Database before.

I have created Business Components for the desired tables and build a simple master-detail Page for Departments and Employees. To verify the app is functioning as expected run in on the integrated WebLogic Server prior to deploying to the Cloud:

Looks good so far.

Prepare ADF Application for Cloud Deployment
Since we want to make the ADF Application connect to the Oracle Cloud Database Service we need to make sure the applications does the right DataSource Lookup. Therefore we need the right JNDI-Name which is pretty easy to find out. 

and take a look at the associated DataSource with your Java Cloud Service.

Now the remaining task is straight forward (at least for everyone who has configured ADF Applications in the past). Open the Application Module and adjust the default configuration accordingly. That means Connection Type = JDBC DataSource with the given name database.


Note: If you want to a single configuration for on-premise and cloud just make sure to create a datasource bound to JNDI Name 'database' in your integrated WebLogic Server.

Make the ADF Application publicly accessible
By default all ADF Application deployed to Oracle Cloud will be automatically secured! When users access the application they will be redirected to authenticate against the associated identity domain. The login screen will look like that

Since I want to make the ADF Application for everyone outside the identity domain accessible there is one simple configuration change in the web.xml descriptor needed.

Just add <login-config/> at the appropriate place and the app will be public.
That's easy. The application is now ready for the Cloud Deployment.

Deploy ADF Application to Oracle Cloud
Goto 'Application > Deploy > 'deployment profile name'
[Deployment Wizard opens]

Select: Deploy to Application Server
Click: Next

Enter Connection Name: <some_conn_name>
Select Connection Type: Oracle Cloud
Click: Next

Enter Username: <Your Cloud Identity user name>
Enter Password: <Your password>


Select Data Center: <Data Center>
Enter Identity Domain: <Your identity domain name>
Service Name: <Your service name, by default it is java>
Click: Next

Test the cloud java connection
Click Next,

The ADF Deployment to the Cloud starts. Follow the processing in the Log window.
After less than 2 Minutes the ADF Application is available in the cloud. 
(If it is not available chances are high my trial oracle cloud account is expired ;) )

Some words on redeployment: On redeployment from the JDeveloper IDE the previously deployed app version is undeployed first. The the new app version is deployed as expected.

Summary 
  • Deploy DB Objects if needed to Oracle Cloud Database
  • Configure Application Module to use Connection Type JDBC DataSource, Name: database
  • Add <login-config /> to your web.xml to make the ADF Application public if needed
  • Setup up Oracle Cloud Application Server Connection
  • Deploy ADF Application via Cloud Server Connection
Conclusion
Everything worked as designed so far. No failure / exceptions occurred to me. Thanks Oracle! Great Work!

Related Posts / Documentation




Managing ADF Applications with Oracle Java Cloud Service Control

$
0
0

In this post I am going to show how to manage and monitor Oracle ADF Applications in the Oracle Cloud using Oracle Java Cloud Service Control.

Prerequisites
You should have the following done before trying the described steps in this post yourself.
Managing tasks
The Oracle Java Cloud Service Control - that's the official name - is a subset of Enterprise Manager Cloud Control 12.1.0.2.0. It supports the Cloud Service Administrator to do the following tasks:
  • View the list of services, metrics and availability of each service instance
  • Deploy / Undeploy / Start / Stop Java EE (ADF) applications
  • View cloud service job logs to see and verify recent activity
  • View and export application log messages
  • View ADF Application performance metrics <<< "does not work for me"
Getting started, Monitor Service Metrics
To get started log in at cloud.oracle.com and open "My Services" tab.

On this screen the first interesting metrics can be monitored per Java service instance.
  • Java Heap usage, averaged over the last 15 minutes
  • CPU usage, averaged over the last 15 minutes

From the service overview we can follow the 'Service Console' Icon that will take us to the 'Oracle Cloud Java Service Control'
The dashboard mainly shows an overview of the service availability and some common used resource usage metrics in different representations (diagram, table) like
  • Active HTTP Sessions
  • Request processing time (in ms)
  • Request count (per minute)
  • Open JDBC Connections
  • Java Heap Usage
  • CPU Usage

Deploy / Undeploy / Start / Stop Java EE (ADF) applications
The next important part is the possibility to Deploy, Undeploy (Delete), Redeploy, Start & Stop Applications. These are common administration tasks which are easy to use without any complications - at least start, stop worked fine so far ;). 

For this post I am going to try deployment of ADF App right from the browser. Let's see if it works (The first ADF Deployment into the Oracle Cloud I have done from JDeveloper IDE, which worked without any problems). So let's click 'Deploy New' 
Choose an EAR from you local machine, give the child a name and press 'Deploy'. 

The upload goes really quick and user is provided with a message which says that a cloud service Job has been started in order to perform the task.
Lesson learned: It is not possible to provide a deployment plan while deploying ADF Applications in the Oracle Cloud.

This brings us to the next feature. 

Cloud service job logs
On the bottom of the cloud control dashboard there is a table panel 'Java Cloud Service Jobs' to track the recent activity. After refreshing the dashboard we notice that the previously started deployment job has failed.

Select the corresponding row and open the 'View Java Cloud Service Job Logs' Menu

The strange thing here (bad UX) is that the service administrator has to guess what actually caused the deployment to fail from 3 options
  • The uploaded EAR might have not passed the virus scan
  • The uploaded ADF Application might have not passed the whitelist validation
  • The deployment failed due to some other issue.
a) For every option you choose from the Menu a file is downloaded and can be viewed on the local machine.
Virus Scan: Passed successful.

b) Next: Application Whitelist Validation
2012-12-29 16:41:23 CST: Starting action "API Whitelist"
2012-12-29 16:41:23 CST: API Whitelist started
2012-12-29 16:41:24 CST: WARNING  - There are 2 warnings(s) found for enpit_cloudapp2.ear.
2012-12-29 16:41:24 CST: WARNING  - Path:enpit_cloudapp2.ear (2 Warnings)
2012-12-29 16:41:24 CST: WARNING   - Path:enpit_cloudapp2.ear (2 Warnings)
2012-12-29 16:41:24 CST: WARNING    - Path:enpit_cloudapp2.war (2 Warnings)
2012-12-29 16:41:24 CST: WARNING     - Path:WEB-INF**** (2 Warnings)
2012-12-29 16:41:24 CST: WARNING      - 1:Recommended child element "jsp-descriptor" missing under element /
               bea-weblogic:weblogic-web-app.
              
               If you have a JSP file that is not pre-compiled, The compilation errors
               could be shown on the browser. It is recommended to include
               <jsp-descriptor><verbose>false<****><****-descriptor> in weblogic.xml.
               Line No:2.
2012-12-29 16:41:24 CST: WARNING      - 2:Recommended child element "session-descriptor" missing under element /
               bea-weblogic:weblogic-web-app.
              
               You will be required to have distinct cookie-path, if multiple
               applications are accessed with in the same SSO session or if you have
               multiple applications with different auth-method(CLIENT-CERT, FORM, BASIC)
                in the same service instance.
               Line No:2.
2012-12-29 16:41:24 CST: WARNING  - enpit_cloudapp2.ear had  2 warning(s).
          
2012-12-29 16:41:24 CST: INFO     - Whitelist validation has completed with 0 error(s) and 2 warning(s).
2012-12-29 16:41:24 CST: Whitelist validation passed.
2012-12-29 16:41:24 CST: "API Whitelist" complete: status SUCCESS


c) Looks like the deployment actually went wrong - and indeed

2012-12-29 16:41:24 CST: Starting action "Deploy Application"
2012-12-29 16:41:24 CST: Deploy Application started
2012-12-29 16:41:40 CST: weblogic.application.ModuleException:
2012-12-29 16:41:40 CST: WLS action state: failed
2012-12-29 16:41:40 CST: Action FAILED with WLS state: failed
2012-12-29 16:41:40 CST: Application deployment failed.
2012-12-29 16:41:42 CST: [Deployer:149034]An exception occurred for task [Deployer:149026]remove application enpit_cloudapp2 on c1.: .
2012-12-29 16:41:42 CST: WLS action state: completed
2012-12-29 16:41:42 CST: "Deploy Application" complete: status FAILED

=> Well so it looks like an exception occurred while 'removing the application on c1". This message does not help really much, is confusing since that was the first deployment and no need for removing a previous application.

Application log messages
Maybe the log messages give some more information about the failure. The messages are accessible by following the link 'View Log Messages'
Looks like there is a configuration exception in the deployed ADF Application. After deploying the same application from JDeveloper into the Cloud I have noticed the Deployment Platform in the Log was 'Oracle Cloud'. So the problem was clear to me. Open the Deployment Profile and adjust the platform to 'Oracle Cloud' for creating the EAR.
After creating the EAR once again with that setting and performing same steps from the Cloud Control as described above the deployment worked as expected.

Important lesson learned: The Deployment Profiles and so the resulting ADF Application EAR differs.  You cannot use the same EAR for Deployment to on-premise WebLogic Server AND Oracle Cloud Java Service! 


ADF Performance metrics
Clicking on a given ADF applications name shows a dedicated performance view
IMHO the displayed metrics cannot be realtime values because most of the testing time -  there were 2 active HTTP sessions all values were displaying 0. So I guess it is an average view over the last 15 Minutes.

From the application menu the ADF Performance view can be opened.

This part is very disappointing for now since the displayed information is just not true!
The sample app is using an Application Module and so should also display application module pool stats as indicated (but empty :( )

Same to the TaskFlows view
Sample application is using two bounded task flows. So I would expect them to be shown up here.


Conclusion
In general the Java Cloud Service Control makes what it is made for. It looks like the observed shortcomings are a limitation to the trial account or the ADF Performance Summary does not work in its current state. It is interesting to see that even in the official Oracle Cloud Documentation (Sec. Monitoring Oracle Java Cloud Service) there is no word left about the ADF Performance Summary + all available screenshots show 0 sessions, 0 requests and so on.

If someone has a different experience or some guy from Oracle has an explanation for the inconsistent  behavior in the Cloud Service Control feel free to comment. I would be happy to be convinced from the opposite - a reliable cloud service control for monitoring ADF Applications.

Enhancement Requests
  • Java Cloud Service Jobs
    • Emphasize failed jobs, e.g. displaying 'Failed' in Red.
    • In case of failed jobs there should be made clear on first view what caused the issue (Virus detected, Whitelist violated, other issue).
    • Error message in case of failed deployment should be more useful. An message like 'An exception occurred for task [Deployer:149026]remove application enpit_cloudapp2 on c1.: .' does not say anything about the cause.
  • Resource Usage metrics (sessions, Request processing time, JDBC Connections)
    • Realtime Values. Currently it looks like the values are most of the time 0 even if there is some load.
  • ADF Performance 
    • Display the actual metric values. Currently AM Pool and Taskflow metrics are not shown.
  • General: Improved Reliability. Sometime there were just errors and inconsistent information displayed (see next image). E.g. error getting datasources and open JDBC Connections = 0 but the DB based application was accessible and worked fine.

Documentation

Related Posts

JDeveloper Code-Template for ADFLogger

$
0
0

 Environment: JDeveloper 11.1.1.6

To make the Logger-Declaration a not so tedious work you can make use of JDeveloper Code Template features which is available in the preferences.
In JDeveloper:

1. Open from the menu: Tools > Preferences
2. Open: Code Editor > Code Templates
3. Click "+" to add a new code template


4. Goto the Code-Tab and add the following:

private static final ADFLogger LOGGER = ADFLogger.createADFLogger($clazz$.class);

5. Goto Imports-Tab and add needed classes:

oracle.adf.share.logging.ADFLogger

6. Confirm Changes by clicking 'OK'.

=>> The Code-Template 'logger' is now available inside the Java-Editor.


Using the Code-Template in JDevelopers Editor

1. Open a Java class
2. Place cursor right inside class definition, type 'logger' and press 'Ctrl+Enter'.


Afterwards the ADFLogger is available inside the Java class.


On the following Blog posts you can find more information around ADFLogger + a CodeTemplates XML which you can import in your JDeveloper.

More information


ADF 11.1.1.7 New Feature: HTML5 Placeholder

$
0
0

Many of us have waited for it some time now. With the arrival of ADF 11.1.1.7 the Input components have got a new attribute: placeholder.

Use Case
Provide a prompt text inside an input component.

Usage

In order to use this feature just fill in the newly added attribute from the property inspector or directly in the source code.


On runtime it is properly rendered as placeholder-HTML5 Attribute.

Works on all modern browsers ;)

ADF: Static Values View Object does not show any values (solved)

$
0
0

Environment
ADF/JDEV 11.1.2.4

Problem description
After creating a ViewObject of Type "static values" and running an instance inside the Business Components tester I noticed that no values are displayed at runtime! From the navigation action it looks like there are exactly as many rows that has been created, but whatever row is displayed, all values are empty!


Analysis
Looking in depth I noticed that the reference to the resource bundle where the static values are coming from, is invalid. The path does not match the actual source for the properties file although the static values ViewObject has been created by the JDeveloper Wizard

Solution
Short term solution is to manually adjust the value of the attribute PropertiesFile of the corresponding ResourceBundle.

So if the Property file is under src/enpit/sample/adf/transientvoascriteria/modelBundle.properties set the value to PropertiesFile="enpit.sample.adf.transientvoascriteria.modelBundle"

Rebuild and restart the BC Tester to verify that everything is working as expected:


Remark
The reason for the mismatch I guess is because JDeveloper does not handle everything correctly if having dots in project names. So take care if you use JDeveloper project names like 'MyApp.Model'. Double check references to the property bundle!



WebLogic Application redeployment using shared libraries - without downtime

$
0
0

Environment
Oracle WebLogic 10.3.6

Use Case
An application that depends on custom shared libraries needs to be redeployed without downtime. That means without interrupting the availability of the application to existing and new clients. Since production redeployment is not available for libraries we need to think about a different approach.

Precondition

A shared library (as war) is deployed (state: active) and targeted to - for simplicity say - AdminServer with the following version settings:

Extension-Name: enpit-common-war-lib
Specification-Version: 1.0
Implementation-Version: 1.0.4

An application references that library in its weblogic.xml in the following way:
<?xml version='1.0' encoding='UTF-8'?>
  <library-ref>
       <library-name>enpit-common-war-lib</library-name>
  </library-ref>
</weblogic-web-app>

The library is referenced without any version information. That means it will reference the highest available deployed library version. That application is successfully deployed and also targeted to AdminServer. Its state is active. It is working correctly, accesses Java classes in the shared library.

Problem

Trying to deploy the existing library (not changing the version information) once again 

java weblogic.Deployer -adminurl t3://eden.local:7001 -username weblogic -password welcome1 -upload -library -targets AdminServer -deploy -source enpit-shared-lib-war.war
results in the following error:

Cannot undeploy library Extension-Name: enpit-common-war-lib, Specification-Version: 1, Implementation-Version: 1.0.4 from server AdminServer, because the following deployed applications reference it: enpittestcommons-reflib.war

=> Makes sense!

Solution Trial 1
We change the MANIFEST.MF of the Shared Library that has to be redeployed to
Implementation-Version: 1.0.5   (the deployed one has 1.0.4)

Lets see what happens

Task 17 completed: [Deployer:149117]deploy library enpit-common-war-lib [LibSpecVersion=1.0,LibImplVersion=1.0.5] on AdminServer.
Target state: deploy completed on Server AdminServer

=> We succeeded. Have a new version deployed!

Question 1
Which version is our running application now using?

Well, the application still uses version 1.0,1.0.4 although it is specified that the highest version should be used. To conclude: The application does not dynamically adopt to the new library version. I think that is good. Otherwise it would be much magic happening in the background.

Question 2
We stop the running application. Now the application shows up in the admin console in state "prepared".
Lets start it again. ... It moves again to state "active".

Which version is our running application now using?

Well, In my simple use case I changed the returned string in the library class to "1.0,1.0.5" according to the new library version. And indeed, my sample app shows the right information.
Library-Version: 1.0,1.0.5

Conclusion: That's a powerful way to update dependencies for an application. All you have to do is just restarting the application. At the time of restart the new version of the library is picked up! Further: we are able to undeploy the unreferenced "old" library (in my case 1.0,1.0.4). Everything works as expected except the use feedback at the admin console looks inconsistent. Selecting the Library no referenced applications are shown in the corresponding section


Question 1
How about production redeployment for the application in that scenario? It would mean that the application would have NO DOWNTIME. So lets give it a try. I have undeployed the sample app and deployed it as follows:

java weblogic.Deployer -adminurl t3://eden.local:7001 -username weblogic -password welcome1 -upload -targets AdminServer -deploy -source enpittestcommons-reflib.war -appversion 1.0
Note: That the web application shows up with a version information.

Next: We are going to update the library to impl. version 1.0.6

Task 24 completed: [Deployer:149117]deploy library enpit-common-war-lib [LibSpecVersion=1.0,LibImplVersion=1.0.6] on AdminServer.
Deployment succeeded!

Next: Instead of restarting the web application we Redeployit with "-appversion 1.1"

Log: weblogic.Deployer invoked with options:  -adminurl t3://eden.local:7001 -username weblogic -upload -targets AdminServer -deploy -source enpittestcommons-reflib.war -appversion 1.1
<05.06.2013 19:14 Uhr MESZ> <Info> <J2EE Deployment SPI> <BEA-260121> <Initiating deploy operation for application, enpittestcommons-reflib.war#1.1 [archive: /Users/ak/Dropbox/community/doag/doag-2013-imc/use-shared-lib-app/enpittestcommons-reflib.war], to AdminServer .>
Task 25 initiated: [Deployer:149026]deploy application enpittestcommons-reflib.war [Version=1.1] on AdminServer.
Task 25 completed: [Deployer:149026]deploy application enpittestcommons-reflib.war [Version=1.1] on AdminServer.
Target state: deploy completed on Server AdminServer

Now we test the existing connection. It still shows
Library-Version: 1.0,1.0.5

Further open a new Browser and target to the same web app URL gives me :

Library-Version: 1.0,1.0.6

After sessions timed out, we get the following picture

Conclusion

Shared Libraries on WebLogic Server in conjunction with "production redeployment" is a really powerful feature. Applications can upgrade to a library version without downtime!

Next I would like to check if same is possible with shared ADF Libraries. That way it would be possible to update separate application parts (deployed as ADF Libraries) without downtime. Would be really cool!


Production Redeployment with ADF Shared WebLogic Libraries

$
0
0

Based on my previous post I wanted to know if we can achieve to redeploy parts of an ADF application by using shared WebLogic Libraries. In conjuction with the production redeployment WLS feature the overall goal is to prove that we can update modular ADF applications without downtime.

Introduction

The sample application consists of an employees taskflow that is bundled as ADF Library and deployed as shared library on WebLogic server. The sample is based on ADF 11.1.1.7 / WLS 10.3.5 / HR Schema.

First step: Create ADF Library as Shared WAR deployment

Goto JDev application with the containing Taskflow:

Create a MANIFEST.MF file under ViewController/src/META-INF/ with the following contents
The important parts are

Extension-Name: enpit.sample.empFlow
Specification-Version: 1.0
Implementation-Version: 1.0

Create ADF Library Deployment Profile for the empFlow on ViewController project with dependency on your Model project.
Make sure only connection name is Included in the Library

Having an ADF Library Deployment Profile in the employee taskflow application we create an additional Deployment profile (of type WAR) in the ViewController project. 

Under  WAR Options include the MANIFEST.MF file

Make sure to remove everything from Web Files contributors since we only want to wrap the ADF Library inside this WAR file.

Same to WEB-INF/classes. Exclude everything.

Under Profile Dependencies add the dependency to the ADF Library Profile

Goto WEB-INF/lib Filters and uncheck everything except the desired ADF Library JAR file.

With that WAR deployment configuration we are able to deploy -  the ADF Taskflow -  as shared library to the WebLogic server. (Select ViewController, right click, Choose Deploy > SharedADFLib ...to Application Server)

As a result the library shows up under Deployments in the WebLogic Admin Console

Deploy master application

In the master application that consumes the taskflow from the ADF Library we need to make sure
  • versioning is configured for application deployment
  • ADF Library is not bundled with the EAR
  • Library reference is added to the ADF Shared Library in weblogic.xml (not weblogic-application.xml)
To enable the versioning for the app deployment we add /src/META-INF/MANIFEST.MF file with the contents
Manifest-Version: 1.0
Weblogic-Application-Version: 1.0

Now goto the EAR deployment profile and add the MANIFEST.MF file under the EAR Options

Goto application descriptors Filters and exclude MANIFEST.MF. (Otherwise the EAR won't be created as JDeveloper will try to include 2 MANIFEST.MF files in the EAR. You will see this exception in the deployment log window).

Now exclude the ADF Library from the application deployment. Goto ViewController project properties of the master application and make sure the library is not deployed by default.

In the WAR deployment profile check that the ADF Library JAR is not included


Next create WEB-INF/weblogic.xml and add library reference to the ADF Shared Library.

Important note: In my first try I added that library reference in the weblogic-application.xml. That won't work. At deployment time there will be the following exception
[08:23:54 AM] [Deployer:149034]An exception occurred for task [Deployer:149026]deploy application enpit_application1 [Version=1.0] on DefaultServer.: javax.faces.context.ExternalContext.
[08:23:54 AM] Weblogic Server Exception: weblogic.application.WrappedDeploymentException: javax.faces.context.ExternalContext
[08:23:54 AM]   See server logs or server console for more details.
[08:23:54 AM] weblogic.application.WrappedDeploymentException: javax.faces.context.ExternalContext
[08:23:54 AM] ####  Deployment incomplete.  ####
[08:23:54 AM] Remote deployment failed (oracle.jdevimpl.deploy.common.Jsr88RemoteDeployer)

So don't try this.

Doing it right you should see the following in Admin Console:

Test the application. It loads the taskflow and displays version 1

Next Step: Test production redeployment based on new version of ADF Shared Library
We are going to 
  • Make changes in employees taskflow
  • Change Library Implementation-Version to 1.1
  • Deploy ADF Library as Shared WLS Library
  • Increase application version to 1.1
  • Redeploy master application
So first we increase the library version
and make some simple changes to the JSFF

Next: Deploy ADF Library to JAR
Next: Deploy sharedADFLib Deployment to IntegratedWebLogic

Check deployment in the Admin Console

Goto the master application and change Weblogic-Application-Version to 1.1

and deploy the master application to Verify deployment in the Admin Console once again. You should notice that previous application (1.0) is in stop running state. Actually it is meant to be RETIRED Mode. Existing web sessions will be served by that version 1.0.

Open a NEW BROWSER WINDOW (a different browser window to be dead sure) and point to the master application URL. You should see new version of the integrated Taskflow.

Conclusion

This mechanism is really powerful. It lets you redeploy application parts - maybe of a huge application - without downtime.

Related Posts

ADF 12c: Model-Driven LOV with Bean Data Control

$
0
0

Introduction

Prior to ADF 12c Model-driven input List-Of-Values (LOV) was a feature exclusively reserved to the ADF BC DataControl. With ADF 12c the Bean DataControl has been enhanced a lot. Now it is possible to create input LOVs the declarative way.

Prerequisites
You have a plain Java Object Model, for which you want to build the UI, including an LOV. In this sample we use Person, Address and a PersonService, which we want to expose as a DataControl
The adressId of Person should be filled through a LOV from available Address-Entities.

How to do it

First, create the DataControl from the PersonService: Right Click the PersonService.java class and Choose: Create DataControl


For this purpose, just keep the defaults in the wizard and complete with "Finish"

Open the generated DataControls.dcx, Select the Collection Type person and choose 'Edit'

The metadata file for the Person entity will be created. Next open the generated metadata file and configure the LOV on addressId as follows

Now the LOV is already configured and could be used for the UI Creation. If needed the LOV can be refined with UI Hints (as known from the ADF BC LOVs)

Now you can go on an build the UI. Drop the persons collection from the Data Control Palette onto the Page and
choose "ADF Form":

As indicated an ADF LOV Input will be crated for the addressId attribute. It can be further adjusted if needed in the next wizard screen

The LOV has been created

and can be tested at runtime.

The LOV Popup contains a query panel to limit the given values. As a wildcard only % is working. no Asterisk (*) what I personally would prefer. Anyway the LOV works as expected. In the sample the adressId is filled correctly.

Validation also works by default. If you try to enter an invalid value an error message pops up.

Further Reading

JDeveloper 12c: Create RESTful Service from Java Class

$
0
0
With JDeveloper 12c finally it is possible to create RESTful Services from a Java Class. The implementation is based on Jersey following the Java EE 6 specification JAX-RS. For testing JDeveloper includes a comprehensive Tooling. In general RESTful services are really popular for mobile applications, e.g. ADF Mobile.

Get started
Create a simple Java Class for your business domain object plus a Service Facade that you want to expose as a RESTful Service.

package enpit.sample.adf12c.pojorest.model;
import java.util.Date;import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {
    private Long id;
    
private String firstname;
    
private String lastname;
    
private Date hiredate;   
    
private Long addressId;

    
public Person() {
        
super();
    }

    
public void setId(Long id) {
        
this.id = id;
    }
    
public Long getId() {
        
return id;
    }
    
public void setFirstname(String firstname) {
        
this.firstname = firstname;
    }

    
public String getFirstname() {
        
return firstname;
    }
}
Make sure to annotate the class with the @XmlRootElement otherwise the REST Service will not work for this domain object.

Next create a simple service facade with some test data, e.g.
package enpit.sample.adf12c.pojorest.model;
import java.util.ArrayList;
import java.util.Date;import java.util.List;

public class PersonService {

    
private List<Person> persons;
    
private Person person;

    
public PersonService() {
        
super();
        
this.persons = new ArrayList<Person>();
        
for (long i = 0; i < 10; i++) {
            Person p = 
new Person();
            p.setId(i);
            p.setFirstname(
"Firstname " + i);
            p.setLastname(
"Last " + i);
            p.setHiredate(
new Date());
            
this.persons.add(p);
        }
        
this.person = this.persons.get(0);
    }

    public List<Person> getPersons(){
        return this.persons;
    }

    public void addPerson(Person person) {
        System.out.println(
"add person " + person);

        
if(person != null){
            getPersons().add(person);
        }
    }
    public Person getPerson(){
        
return person;
    }
}

So far there is nothing special. 

Create RESTful Service with the help of JDeveloper 12c
Now comes the interesting part. Select the PersonService.java in the application navigator and
choose "Create RESTful Service…"

You will get a wizard to specify the RESTful Service interface. Set the desired root path. Choose the desired media types and the Methods you want to expose as REST Service
After finishing the wizard the following happens
- JAX-RS Annotations are generated  on the Java Class
package enpit.sample.adf12c.pojorest.model;
import java.util.ArrayList;
import java.util.Date;import java.util.List;import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;import javax.ws.rs.POST;import javax.ws.rs.Path;import
 javax.ws.rs.Produces;


@Path(
"rest")
@Produces(value = { "application/json""application/xml" })
@Consumes(value = { "application/json""application/xml" })
public class PersonService {

    
private List<Person> persons;
    
private Person person;

    
public PersonService() {
        
super();
        
this.persons = new ArrayList<Person>(){
        
for (long i = 0; i < 10; i++) {
            Person p = 
new Person();
            p.setId(i);
            p.setFirstname(
"Firstname " + i);
            p.setLastname(
"Last " + i);
            p.setHiredate(
new Date());
            
this.persons.add(p);
        }
        
this.person = this.persons.get(0);
    }

    @GET
    @Path(
"/persons")
    
public List<Person> getPersons(){
        
return this.persons;
    }

    @POST
    @Path(
"/person")    
    
public void addPerson(@FormParam("person"Person person) {
        System.out.println("add person " + person);

        
if(person != null){
            getPersons().add(person);
        }
    }

    @GET
    @Path(
"/person")
    
public Person getPerson(){
        
return person;
    }
}

- web.xml is created. The Jersey Servlet is configured properly.


         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0"]]>
 
    jersey
    com.sun.jersey.spi.container.servlet.ServletContainer
    1
 
 
    jersey
    /resources/*
 


Testing the RESTful Service in JDeveloper 12c
Jdeveloper is quite powerful. It lets you test the RESTful service right in the IDE.
Right-Click on the PersonService.java class and choose Run.

In background WebLogic Server 12c starts and the RESTFul Service gets deployed.

The WADL is kind of WSDL for RESTful Services. Clicking on the "Target Application WADL" URL brings you to the overview of the provided service operations

You can test each Service Operation right from the IDE. Pressing the "Test" Button brings you to the HTTP Analyzer Screen.
Here you can choose the Method, change HTTP Headers (e.g. what kind of media type you want to accept).
Press "Send Request" to actually test the Service Operation. Make sure to change the view to "HTTP Content" not "WADL Structure" otherwise you want see the pretty formatted output on the right hand side.

Change the Accept-Header to application/json and send the request again. The output automatically will be in JSON format.
The HTTP Analyzer is even so good to parse the POST Parameter to create a good looking form for data entry

Conclusion
Creating and Testing RESTful Services is really simple with JDeveloper 12c.

ADF: Creating a custom train button bar, reflecting the disabled state

$
0
0
Requirement

In some cases there is a need to obtain more control over the ADF train button bar. The generated default does not allow to add an additional actionListener.



Environment

JDeveloper/ADF 11.1.1.7

Solution

There is a simple solution I found on http://www.adftips.com/2010/10/adf-ui-how-to-specify-actionlistener.html to create custom buttons for the previous / next functionality.


But there is still one thing missing. The buttons are always enabled. Unfortunataly there is no easy way to set the disabled property right from the given trainModel that is accessible by EL.

To solve this we create a managed bean as follows:



Now it is possible to bind the properties for disabled status




Similiar posts


WebCenter: Checking the installed version information

$
0
0
Use Case

While installing WebCenter Portal 11.1.1.8 you will see a screen like the following during the domain creation

First I thought there is something wrong but beeing some time with Oracle technology now I know that these version information might just not be the one you really installing.

So the purpose of this post is to double check the WebCenter version once installed.

Check installed versions with OPatch

Create a checkversion.sh script like the following

export MW_HOME=/oracle/fmwhome11118
export ORACLE_HOME=$MW_HOME/Oracle_WC1
export JAVA_HOME=/oracle/javahome/jdk1.6.0_29
export PATH=$JAVA_HOME/bin:$PATH

java -version

$ORACLE_HOME/OPatch/opatch lsinventory -details -jdk $JAVA_HOME

The setting of Oracle is needed in order to run OPatch successfully.
Next run the script from the command line:

[oracle@soabpm-vm fmwhome11118]$ sh checkversion.sh
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)
Oracle Interim Patch Installer version 11.1.0.9.9
Copyright (c) 2012, Oracle Corporation.  All rights reserved.


Oracle Home       : /oracle/fmwhome11118/Oracle_WC1
Central Inventory : /oracle/oraInventory
   from           : /oracle/fmwhome11118/Oracle_WC1/oraInst.loc
OPatch version    : 11.1.0.9.9
OUI version       : 11.1.0.9.0
Log file location : /oracle/fmwhome11118/Oracle_WC1/cfgtoollogs/opatch/opatch2013-08-17_06-35-49AM_1.log


OPatch detects the Middleware Home as "/oracle/fmwhome11118"

Lsinventory Output file location : /oracle/fmwhome11118/Oracle_WC1/cfgtoollogs/opatch/lsinv/lsinventory2013-08-17_06-35-49AM.txt

--------------------------------------------------------------------------------
Installed Top-level Products (1):

Oracle WebCenter Portal Suite 11g                                    11.1.1.8.0
There are 1 products installed in this Oracle Home.


Installed Products (42):

Application Server 11g Cloning Component                             11.1.1.8.0
Installer SDK Component                                              11.1.0.9.0
Jython                                                               11.1.1.7.0
Oracle Bali Share                                                    11.1.1.7.0
Oracle Business Process Management Process Spaces                    11.1.1.7.0
Oracle Display Fonts                                                 11.1.1.7.0
Oracle Extended Windowing Toolkit                                    11.1.1.7.0
Oracle Fusion Middleware Admin Config                                11.1.1.6.0
Oracle Help for Java                                                 11.1.1.7.0
Oracle Help for the Web - UIX                                        11.1.1.7.0
Oracle Help for the Web Shared Library                               11.1.1.7.0
Oracle Help Share Library                                            11.1.1.7.0
Oracle Ice Browser                                                   11.1.1.7.0
Oracle Jakarta                                                       11.1.1.7.0
Oracle JFC Extended Windowing Toolkit                                11.1.1.7.0
Oracle JGroups                                                       11.1.1.7.0
Oracle JSCH                                                          11.1.1.7.0
Oracle One-Off Patch Installer                                       11.1.0.9.9
Oracle Remote Diagnostic Agent                                       11.1.1.7.0
Oracle Remote Intradoc Client                                        11.1.1.8.0
Oracle SOA workflow                                                  11.1.1.7.0
Oracle UIX                                                           11.1.1.7.0
Oracle Universal Installer                                           11.1.0.9.0
Oracle Upgrade Assistant                                             11.1.1.8.0
Oracle Upgrade Assistant                                             11.1.1.8.0
Oracle Upgrade Assistant for Webcenter                               11.1.1.8.0
Oracle WebCenter Portal Suite                                        11.1.1.8.0
Oracle WebCenter Portal Suite 11g                                    11.1.1.8.0
Oracle WebCenter Portal: Activity Graph                              11.1.1.8.0
Oracle WebCenter Portal: Analytics Collector                         11.1.1.8.0
Oracle WebCenter Portal: Discussions Server                          11.1.1.8.0
Oracle Webcenter Portal: Framework                                   11.1.1.8.0
Oracle Webcenter Portal: Framework Core                              11.1.1.8.0
Oracle WebCenter Portal: Pagelet Producers                           11.1.1.8.0
Oracle WebCenter Portal: Personalization                             11.1.1.8.0
Oracle Webcenter Portal: Portlet Server                              11.1.1.8.0
Oracle WebCenter Portal: RCU                                         11.1.1.8.0
Oracle Webcenter Portal: Spaces                                      11.1.1.8.0
Oracle WebCenter Portal: Suite Components                            11.1.1.8.0
Oracle WebCenter Portal: Wiki                                        11.1.1.8.0
Oracle WebLogic Communications Service Client Library                11.1.1.7.0
OracleAS Documentation                                               11.1.1.8.0
There are 42 products installed in this Oracle Home.


There are no Interim patches installed in this Oracle Home.


--------------------------------------------------------------------------------

OPatch succeeded.
[oracle@soabpm-vm fmwhome11118]$

Further information
If you want to try out WebCenter follow the links for more information

Download WebCenter Portal 11.1.1.8

Neue Features und Änderungen in WebCenter Portal  11.1.1.8.0
http://docs.oracle.com/cd/E29542_01/doc.1111/e27603/whatsnew.htm#sthref8

See more Screenshots of the WebCenter Portal  11.1.1.8.0 on our german blog
http://www.enpit.de/webcenter-portal-11-1-1-8-mit-zahlreichen-neuerungen/

ADF 11gR1: How to improve the UX of tables with filter

$
0
0

In a typical Oracle ADF application there might be a lot of tables with the query-by-example filter functionality. It is a great ADF standard feature that users love. However there is at least one thing that can be improved.

Use Case
Step 1: The user enters a filter criteria and performs the filtering.

=> The table data is filtered according to the criterion

Step 2: The user clicks on "QBE-Filter" button
=> The filter header row is not visible.
=> The table data is still filtered 
=> There is no hint for the user whether the data is filtered and if so how the data is filtered. From UX point of view the UI Feedback is not perfect.

How to improve
To  improve the user feedback it would be great to at least have a UI hint if the visible data is filtered or if the "Hide QBE-Filter" button would reset the filter. In this blogpost I am going to show a hack how you can achieve the latter one with ADF 11R1. 

Step 1: Create a Javascript file with the following content

The hack is to actually override the default showQBE function with a custom function that queues an AdfQueryEvent to clear all filter criteria before calling the default ADF showQBE function.

To register this override in JavaScript you must register a clientListener for the onLoad event in the JSF page.


Environment

Tested with
ADF 11.1.1.6 normal mode
ADF 11.1.1.7 normal and screenReader mode.

To my surprise this improvement is implemented in ADF 12.1.2! No need to hack if you are on the bleeding edge :)

Disclaimer
The described feature uses an unsupported ADF JavaScript Hack! So use on your own risk if your users want it and your stuck on 11gR1.

Content Integration through WebCenter Pagelets in WebCenter 11.1.1.8

$
0
0
Introduction
In this blogpost I am going to show how to integrate web content into WebCenter Pages by using a so called Pagelets - created by the WebCenter Pagelet Producer.

The Pagelet technology is pretty powerful. It acts like a proxy and works as a clipper for remote web content. It has its roots in WebCenter Ensemble and before that in Plumtree.

Prerequisites
The Pagelet Producer is part of a separate application (pagelet-producer) that by default runs on the WC_Portlets Managed server. So make sure that server is running.

Create a pagelet
To create a pagelet open the WebCenter Pagelet Producer Console at http://localhost:8889/pagelets/admin and login with the weblogic admin user.

Step 1: Create new Resource
Next: Select Producer Type: Web
Next: Give it a name, Define the Source URL etc.

Next: Define a pagelet: bundesliga-tabelle. The URL-Suffix is used to identify a specific resource from the source URL.

Now move on and create a new clipper. (With a clipper we actually are going to clip a portion of the source web page)

Next comes the most interesting + impressive part. Choose 'Content' and launch clipper. There you will be able to open the source web page in the clipper and choose the desired region:
As a result the 'clipping path' is updated. Save all changes.

Now we can test the pagelet under the 'Documentation" item.
As you can see the Pagelet is embeddable in any simple web page, not only WebCenter based.

Calling the the Pagelet URL in a new Browser-Tab we see that our pagelet is working. 
BTW: All Links are rewritten by default so it is working through the pagelet producer proxy. The clipped content can further be customized through so called 'Injectors' but I am not going to show that in this blog post. Please refer to the documentation (see links below).

Use Pagelets in the Portal Builder
To use the created pagelets in WebCenter Portal, the pagelet producer needs to be registered first.
Go to WebCenter Portal Administration > Tools and Services > Portlet-Producer. Choose 'Register'. Provide the given Producer URL as shown below.
Clicking on OK brings you to the overview page. The created pagelets should show up for the registered provider.
Next. Check if the Pagelets are listed under  "Shared Assets > Pagelets".

Now we can add the pagelets by using Portal Builder for a custom page. In the Portal Builder from the catalog choose ' UI Components > Pagelet-Producer > enpit Pagelets > 'pagelet-libraryname' > 'pagelet' ' and add it by drag and drop to your page. In my sample it looks like that

Save the page and open in view mode

That's it. WebCenter Pagelets - a great, powerful technology!

Gotchas
A) The pagelets is embedded inside an iframe by default. If I disable that option
there is an exception in the Portal Builder

I guess Portal Builder tries to embed  all the css, javascript, etc into the main web page which leads to an error. Just my assumption. If anyone knows more please comment!

B) The UI of the WebCenter Pagelet Producer Admin Console is really poor in terms of usabiliy, UX, etc. I hope it will be improved or/and will be embedded into WebCenter Portal Administration.

Related documentation

Setup WebLogic 12c environment with Vagrant and Puppet

$
0
0
For one of my presentations at DOAG 2013 I wanted to play around and checkout new features with the latest WebLogic version 12.1.2. To save some time and get experienced in some of the cool DevOps tools I gave a try for Vagrant and Puppet to setup a fresh new WebLogic 12c machine. BTW: All this is possible due to the impressive work Edwin Biemond has done in the last weeks and month (Checkout his powerful puppet modules https://github.com/biemond/puppet/) plus the Vagrant based provisioning script of Matthew Baldwin. (Checkout his recent blog post about that  http://vbatik.wordpress.com/2013/10/11/weblogic-12-1-2-00-with-vagrant/)

To give you a better overview of what I am going to do I created a simple diagram:

I am running the following test drive on Mac OS 10.8.5

Prerequisites
On your host system make sure the following tools are installed

1) Oracle VirtualBox 4.3
2) Vagrant 1.3.5
3) git

Before going on just open 'Terminal' and check if the command line tools are available.

akmac2:~ ak$ vagrant -v
Vagrant 1.3.5
akmac2:~ ak$ git --version
git version 1.7.12.4 (Apple Git-37)


Configuring the desired VM
akmac2: $ cd /Users/ak/Workspace/github
akmac2:github ak$ git clone https://github.com/matthewbaldwin/vagrant-wls12c-centos64.git
Cloning into 'vagrant-wls12c-centos64'...
remote: Counting objects: 280, done.
remote: Compressing objects: 100% (179/179), done.
remote: Total 280 (delta 90), reused 255 (delta 71)
Receiving objects: 100% (280/280), 612.79 KiB | 90 KiB/s, done.
Resolving deltas: 100% (90/90), done.
akmac2:github ak$
-------

Next I made some changes to the Vagrantfile and the provisioning script site.pp in order to get the binaries from my external software repository drive. The path on my local machine to the software binaries is as follows:
- /Volumes/EXT_AK_1TB/Downloads/oracle/oracle.java/jdk-7u25-linux-x64.tar.gz
- /Volumes/EXT_AK_1TB/Downloads/oracle/oracle.weblogic/wls_121200.jar

Changes to Vagrantfile done:
config.vm.synced_folder "/Volumes/EXT_AK_1TB/Downloads", "/software"

Changes to puppet/manifests/site.pp done:
...
jdk7::install7{ 'jdk1.7.0_45':
      version              => "7u45" , 
      ....
      sourcePath           => "/software/oracle/oracle.java",
  }
...
$puppetDownloadMntPoint = "/software/oracle/oracle.weblogic"


Now everything is set up to boot and provision the VM:
akmac2:vagrant-wls12c-centos64 ak$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Box 'centos64' was not found. Fetching box from specified URL for
the provider 'virtualbox'. Note that if the URL does not have
a box for this provider, you should interrupt Vagrant now and add
the box yourself. Otherwise Vagrant will attempt to download the
full box prior to discovering this error.
Downloading or copying the box...
Progress: 0% (Rate: 93585/s, Estimated time remaining: 3:23:20)

Successfully added box 'centos64' with provider 'virtualbox'!
[default] Importing base box 'centos64'...
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] -- 80 => 8888 (adapter 1)
[default] -- 7001 => 7001 (adapter 1)
[default] Running 'pre-boot' VM customizations...
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Setting hostname...
[default] Mounting shared folders...
[default] -- /vagrant
[default] -- /software
[default] -- /tmp/vagrant-puppet/manifests
[default] -- /tmp/vagrant-puppet/modules-0
Running Puppet with site.pp...
Info: Loading facts in /tmp/vagrant-puppet/modules-0/wls/lib/facter/oracle_middleware_homes.rb
Warning: Unrecognised escape sequence '\/' in file /tmp/vagrant-puppet/modules-0/jdk7/manifests/install7.pp at line 93
Notice: Compiled catalog for wls1212.enpitlocal.de in environment production in 2.03 seconds
...
Notice: /File[stopNodeManager.sh]/ensure: created
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 572.02 seconds
akmac2:vagrant-wls12c-centos64 ak$

Vagrant automatically created the VM in the VirtualMachines folder of your VirtualBox.
and integrated it into the VirtualBox Manager

BTW: The downloaded vagrant boxes are stored in ~/.vagrant.d/boxes. During the download the stream is temporarily stored in ~/.vagrant.d/tmp. So make sure to have enough space in your home directory.


Working with the WLS 12c machine
Well this is pretty easy. Just run
vagrant ssh

to log into the running VM as user vagrant.

Typically you would like to work as oracle user. Just do
wls12c$ su oracle 

By default the root user is locked for security reasons. Any admin tasks can be done as vagrant user by sudo. Nevertheless you can unlock the root user with the following command

# After logging in as vagrant 
$ sudo passwd -u root 

Afterwards you can login with user root and pwd vagrant.

Minor Issues
(1)Vagrant provisioning with puppet
Info: Loading facts in /tmp/vagrant-puppet/modules-0/wls/lib/facter/oracle_middleware_homes.rb
Warning: Unrecognised escape sequence '\/' in file /tmp/vagrant-puppet/modules-0/jdk7/manifests/install7.pp at line 93

=> The Warning looks a bit strange but seems not to break the provisioning run!

(2)Trying to run the "service nodemanager_Wls12c start" I got an exception

oracle@wls1212 ~]$ service nodemanager_Wls12c start
/etc/init.d/nodemanager_Wls12c: line 31: /lib/lsb/init-functions: No such file or directory
[oracle@wls1212 ~]$

Solution: Commenting out line 31 in the init script worked for me ;)


Most important vagrant commands for a managed VM
$ vagrant up (on the first run the VM box is downloaded if needed, booted and provisioned by the configuration of the Vagrantfile. On any further runs the VM box is just booted but not provisioned.)

$ vagrant ssh (Logs into the running VM as user vagrant)

$ vagrant up --provision (Boot the VM and provision by the configuration of the Vagrantfile)

$ vagrant halt (shuts down the running VM)

$ vagrant reload (equivalent of running 'vagrant halt' and 'vagrant up')

$ vagrant reload --provision (equivalent of running 'vagrant halt' and 'vagrant up'  and 'vagrant provision')

$ vagrant suspend (Suspend the running VM)

$ vagrant resume (Resume the suspended VM)

$ vagrant provision (Run the provision scripts against the running VM. Great to test script changes)

$ vagrant destroy (The VM will be completely destroyed. Space is freed.)

Conclusion
The combination of Vagrant / Puppet / Puppet Oracle Modules is extremely powerful. It is possible to create predictable,  preconfigured "VMs from code". With this powerful set of scripts and tools it is quite easy to create new environments based on different Oracle FMW Versions. I guess that we (enpit) will automate the creation and configuration of our environments in the future.

Further information

ADF: Handling exceptions from BackingBeans inside bounded Taskflow explained

$
0
0

Scenario 1

Exception is thrown in actionListener Code for a commandButton inside a View of a bounded taskflow based on page fragments.

In our example Test1ViewBean is in Request-Scope and contains an ActionListener method that throws a NullPointerException for demo purposes.

 This ActionListener is called from a command button


The Default behaviour in this scenario is the following:


Of course this is not user friendly (+ may cause side effects) so we should use one of the provided ADF Exception handling mechanisms to fix that.

Solution to scenario 1:

Make a guess: (a) DCErrorHandler (b) BTF-Exception-Handler (c) UTF-Exception-Handler (d) Faces-ExceptionHandler (e) Servlet-Exception Handler

Tam da da dam: Solution is "(c) UTF-Exception-Handler" not "(b) BTF-Exception-Handler" as some of you might expect. 

Let's see how it works. Create a Method-Activity in adfc-config.xml
and mark it as Exception-Handler.


The Method Activity points - by EL -  to the following java method:

  public void handleExceptionShowMessageInPopupDialog() {
    ControllerContext cc = ControllerContext.getInstance();

    Exception ex = cc.getCurrentViewPort().getExceptionData();
    String message = ex.getMessage();


    FacesContext fc = FacesContext.getCurrentInstance();
    FacesMessage facesMessage =
      new FacesMessage(FacesMessage.SEVERITY_ERROR, "UTF: " + message, null);
    fc.addMessage(null, facesMessage);

    cc.getCurrentRootViewPort().clearException();
    fc.renderResponse();

  }
Having this Exception-Handler active on runtime the Exception is catched an displayed in a user friendly inline popup



Why the "(b) BTF-Exception-Handler" is not working in the given scenario?
Well, it is because the action event is handled in the standard JSF Lifecycle (invoke application phase) and not inside the ADF Controller of the bounded taskflow.


Download

In the sample application - based on ADF 11.1.1.7 - you can test the different cases and see how everything works in each scenario. enpit.sample.adf.testExceptionHandling-jdev11117.zip

Further Reading



ADF Faces: How to skin a great looking breadcrumb

$
0
0

Although the default ADF Skin is fine for many UI requirements, there are often special customer needs for specific design. In this short blogpost I am going to show how you can skin a great looking breadcrumb (with plain CSS). The following picture shows what I am talking about:
Usage
Inside ADF Pages it should be is easy to create such a breadcrumb:

<af:panelList id="pl1" styleClass="MyBreadcrumb">
    <af:commandLink text="Home" id="cl1" />
    <af:commandLink text="commandLink 2" id="cl2"/>
    <af:commandLink text="commandLink 3" id="cl3"/>
</af:panelList>

Environment
Created with ADF 11.1.2.4 (but should also work with 11gR1 oder 12c)
Tested with current versions of

  • Safari
  • Chrome
  • Firefox
  • IE 9

How to do it
Create a custom ADF Skin with the following CSS Statements

af|panelList.MyBreadcrumb ul {
    list-style: none;
    overflow: hidden;
    display: block;
    padding-left: 0px;
}

af|panelList.MyBreadcrumb li {
    float: left;
    /*display: list-item;
    text-align: -webkit-match-parent;*/
   
}


af|panelList.MyBreadcrumb li:first-child a {
    padding-left: 10px;
    background: gray;
}

af|panelList.MyBreadcrumb li:first-child a:after {
    border-left-color: gray;
}

af|panelList.MyBreadcrumb li a:hover:after {
    border-left-color: red;
}

/*af|panelList li:nth-child(2) a {
   
}*/
af|panelList.MyBreadcrumb li a span {
    color: white;  
}

af|panelList.MyBreadcrumb li af|commandImageLink {   
    color: white;
    text-decoration: none;
    padding: 4px 0 5px 55px;
    background: #eee;
    position: relative;
    display: block;
    float: left;
}


af|panelList.MyBreadcrumb li af|commandImageLink:text-only,
af|panelList.MyBreadcrumb li a {

    color: white;
    text-decoration: none;
    padding: 10px 0 10px 55px;
    background: #bbb;
    position: relative;
    display: block;
    float: left;
   
}

af|panelList.MyBreadcrumb li a:hover {
    background: red;
    text-decoration: none;
}


af|panelList.MyBreadcrumb li a:before {
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-top: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 30px solid white;
    position: absolute;
    top: 50%;
    margin-top: -50px;
    margin-left: 2px;
    left: 100%;
    z-index: 1;
}

af|panelList.MyBreadcrumb li a:after {
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-top: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 30px solid #bbb;
    position: absolute;
    top: 50%;
    margin-top: -50px;
    left: 100%;
    z-index: 2;

Hint
I know that the usage of direct HTML Selectors in ADF Skin files is not a good practice because the skin could break if upgrading to a new ADF Version. If you like feel free to improve the CSS.

Download


References

Create RESTful services on top of ADF Business Components

$
0
0

Introduction

Creating SOAP Services on top of ADF Model is for a long time quite easy and convenient. In JDeveloper: Open an ApplicationModule goto WebService Tab and create a Service Interface by exposing some given ViewObject Instances or custom Service methods. See http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52adf-1735897.html (Consume Early, Consume Often) for more details and great explanation or take a look in the official Oracle documentation http://docs.oracle.com/cd/E23943_01/web.1111/b31974/bcextservices.htm#CJAJGIEB (11 Integrating Service-Enabled Application Modules)

Options to create RESTful Services on top ob ADF BC Model

Creating a RESTful Service Fassade on top of existing ADF Business Components Model is not that straightforward. From different „announcements" we know that Oracle plans to generate RESTful Services ADF BC SDO (Service Data Object) in the future. But for now we need a custom solution.

Exploring various possibilities I came up with the following


Note that the Service Facade is optional but recommended in terms of „separation of concerns", „service virtualization", „clean code", etc. Watch the youtube ADF Insider Essentials for the detailed explanation of the Service Facade Pattern.

Going from top to bottom in the diagram we have the following options
a) ADF BC -> SDO Service Interface -> WebService  -> SOAP 
b) ADF BC -> SDO Service Interface -> Inject EJB in REST-Resource -> REST
c) ADF BC -> Use AM Instance programmatically in REST-Resource ->REST
d) this one is planned for some 12.1.3+ release (and in future will be the default option to expose RESTful Services for a given ADF BC Model).

In this post I am covering case b. I did not find a sample on the web yet. So I give it a try cause it looks like THE pragmatic approach so far.

Howto

For the example I am using JDeveloper 12.1.2 and the corresponding Runtim ADF 12.1.2. In order to understand the next steps I assume you know the basics of ADF and JDeveloper.

1. Create ADF BC SDO SOAP Service for an Application Module:
Open the AM in „Overview", goto "Web Service" Tab. Now open the dialog to create the service interface.

Choose the desired VO-Instances and apply you changes.

JDeveloper should generate some files now. If you take a look in the *ServiceImpl.java Class you will notice that  it is exposed as Stateless Session EJB. This is great!

Because from now on you can use the EJB in a REST-Resource to expose it as RESTful-Service. That's what we are planning to do next.

But before this step test your generated (SOAP-based) service first: Make sure you do not ran into the „StackOverflowException" because the SDO Service will try to traverse the ViewLinks recursively. So the following exception might be the one you will run into.

To fix this, open the corresponding ViewLink and uncheck the property „Generate Property in SDO"


2.  Next: Create a new Project for the RESTful Service
Use the right project template from the NEW-Wizard

Open the NEW-Wizard again and create a RESTful service from new

Deselect the Checkbox in front of GET-Method. We are going to do that later in Sourcecode.

Finish. => This should generate a Java class and configure the project with the Jersey Library.
For the sample to complete the project needs on more adjustment in the project properties. 
- One more Library (Context and Dependency Injection CDI)
and a dependency to the Model-Project because the RESTfulWebService project need access to the application module.

Thats all for the project setup.

3. Add some classes, annotations and the methods you want to expose

import javax.ejb.EJB;

import javax.inject.Singleton;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import oracle.jbo.service.errors.ServiceException;

@Singleton
@Path("api")
public class HrRESTResource {
   
    @EJB
    HRAppModuleService serviceBean;
   
    public HrRESTResource() {
    }
   
    /**
     * getEmployeesView1: generated method. Do not modify.
     */
    @GET
    @Path("emp/{empId}")
    @Produces(value = { "application/json", "application/xml" })
    public EmpResult getEmployeesView1(@PathParam("empId") Integer employeeId) throws ServiceException {
       
        EmployeesViewSDO empSDO = serviceBean.getEmployeesView1(employeeId);
       
        EmpResult result = new EmpResult();
        result.setEmployee(empSDO);
       
        return result;
    }
   
    @GET
    @Path("depts")
    @Produces(value = { "application/json", "application/xml" })
    public DeptResult findAllDepartments() throws ServiceException {
        DeptResult result = new DeptResult();
        result.setDepartmentList(serviceBean.findDepartmentsView1(null, null));
       
        return result;
       
    }
}

Important note: For what ever reason you need to annotate the REST-Resource with @javax.inject.Singleton. Otherwise the EJB-Injection won't work.

Just reuse the SDO-Entity-classes (eg. EmployeesViewSDO), but wrap them inside a custom „Result"-class which should be annotated with @XmlRootElement (JAX-B Standard). 

@XmlRootElement

public class DeptResult {
    public DeptResult() {
        super();
    }
   
    @XmlElement(name="departments")
    private List<DepartmentsViewSDO> departmentList;

    public void setDepartmentList(List<DepartmentsViewSDO> departmentList) {
        this.departmentList = departmentList;
    }

    public List<DepartmentsViewSDO> getDepartmentList() {
        return departmentList;
    }
}
See attached sample application for the whole source code.

4. Run an see the RESTful service in action

As a result we will get the proper JSON structure


if changing the accept- Header to: application/xml we will get XML-Result. 

This is pretty cool. Because we can reuse the generated ADF BC SDO SOAP Service Layer as EJB for the REST Fassade.

Download sample application, based on Version ADF 12.1.2: enpit.sample.adf12.restadfbc-jdev1212.zip

More Information



How to use the Deck component (ADF 12.1.3 New Feature)

$
0
0
With the arrival of ADF 12.1.3 many new features has been introduced. One of those features is the brand new deck ui component. In this blogpost I want to give an example on how to use that new component.

Use Case

The use case is quite simple. Arrange pictures of soccer players in a grid. Once clicked on a picture it is flipped. On the backside you can see more details for the given player. Clicking once again on the card it flips back and shows the picture again. Let's look at the result:
Now clicking on the first pic it flips (with an animated transition) and show details.

How to implement

To implement the described use case create a panelGridLayout first with the following properties

  • row: Fixed height
  • cell: Fixed width, halign="stretch" and valign="stretch"

Inside each cell place the new af:deck component with two links as child components and two transition operations.
The commandLinks act as clickable cards on the deck. Each transition operation defines the desired animation when transitioning from one card to another. There are a lot of out-of-the-box transitions available as you can see in the screenshot.
Which card is currently displayed on the deck is controlled by the displayedChild attribute. It expects the component id of the given child ui component (in this case the af:commandLinks). The interesting piece of JSF Code for the sample to work is as follows:

To make the sample complete a backing bean is needed to handle the action events on each command link. Main task of the action listeners is to change the displayedChild attribut on the deck component and repaint it on the client (through a partial refresh)
While implementing the deck sample I did not want to use the deprecated af:commandLink. But converting it to af:link implies a JSF compilation error. So I switched back to the deprecated component.

Looks like the new Link Component is not fully compatible. Is this a bug?

Further Information



Viewing all 63 articles
Browse latest View live