Tuesday, July 28, 2009

Using Trinidad in JDeveloper 11g

2 scenarios -

1. Trinidad enabling a Fusion Web App (ADF)

Right click on the ViewController Project





Click "Add"

Select the 2 Trinidad Libraries



Click the checkbox "Show Tag Library in Palette"





Use...



2. Using Trinidad standalone

Create a "Generic Application" or a "Java EE Web Application"
In the case of the "Java EE Web Application" right click on the ViewController project and attach the Trinidad libraries as detailed above.

In the case of the "Generic Application" right click on the project you created and attach the Trinidad libraries as detailed above.

Friday, July 17, 2009

Recovering Weblogic Domain administrator password

The scenario - I have installed WLS and forgotten the weblogic domain admin password -

A big thanks to my colleague Silviu for this workaround -

1. At the command line, change directory to the domain and run the setEnv or setDomainEnv script to set the PATH and CLASSPATH.
2. cd /security
3. mv DefaultAuthenticatorInit.ldift DefaultAuthenticatorInit.ldift_BKP
4. run java weblogic.security.utils.AdminAccount ./
-above command will Create a new DefaultAuthenticatorInit.ldift

4. cd /servers//data/ldap
5. mv DefaultAuthenticatormyrealmInit.initialized DefaultAuthenticatormyrealmInit.initialized_BKP
6. Restart the Admin Server.
7. Login with new username/password

* To change the old admin user identity, log into the admin console and change the password from console.

Possible error, due to missing library? -->( Error: Native Library(terminalio) to read the password securely from commandline is not found).

add -Dweblogic.management.allowPasswordEcho=true in setDomainEnv script to be allowed to enter the password in echo mode.

After that, log in as the new user and change the password of user weblogic.

Instance tracking in Oracle SOA Suite 11g

An quick and easy solution to the question - Where is my purchase order? -
with Oracle SOA Suite 11g.

In this simple scenario we will process a purchase order via Mediator - BPEL -Human Workflow-File Adapter(Write2File)

The xsd is as follows -




Start JDev and create an empty composite -

1. Create a New Application of type SOA
2. Composite template = Empty Composite
3. Add a Mediator component. Template = 1 way interface. Check the checkbox "Create Composite Service with SOAP bindings". Set the input type to purchase order.



4. Add a BPEL component - ProcessOrder




5. Wire the Mediator to the BPEL process



6. Create the transformation in the Mediator



7. Add an Assign activity to the BPEL process. In this first draft I simply
assign input to output and then set the element of the output to "valid"



8. Deploy and Test



7. View audit trail



Very nice overview, but still no easy way to find out what has happened to order nr "123" for example.

8. Return to JDev and add a composite sensor (skittle icon)



9. Set as follows -



10. Re-deploy and Test



11. Click on the Instances tab



12. Click on the "Add Fields" button and select the sensor we just created



13. Search for Order Nr "1234"

Thursday, July 16, 2009

Buy this book - Oracle SOA Suite Developers Guide

I've just being going through this book, written by 2 of my Oracle colleagues - Matt Wright and the champion hill climber himself - Antony Reynolds.

The book goes well beyond the mechanics of how to use the Oracle SOA Suite components. There are plenty of architectural recommendations,implementation tips and tricks etc. that make this book really worthwhile reading.

As James Joyce would say - " a veritable fount of knowledge" -

http://www.packtpub.com/developers-guide-for-oracle-soa-suite-10gr3/book

Wednesday, July 15, 2009

Auto-refreshing ADF11g Gantt Project control

The scenario is as follows - I have 2 simple tables - TASK and SUBTASK
(SQL ddl script is at the end of this post)

I want to display the data in a Gantt project control as follows -



I also want this control to auto-refresh when the underlying data changes.

Step 1. Create an ADF Fusion APP in JDev 11g

Step 2. In the Model Project - add ADF Business Components --> Business Components for Tables. Select the tables - TASK and SUBTASK.

Step 3. Add an extra ViewObject based on SUBTASK specifically for the Gantt chart.

Step 4. Create a new ViewLink between the new ViewObject and the TaskView


You should end up with something like this -



Step 5. Set the property AUTO-REFRESH = true for all the View Objects.
Step 6. Create the Java ViewObjectImpl classes for TaskView and SubtaskView.
Step 7. Add the following code after the constructor in TaskViewImpl.


long lastRequeryTask = 0;
public long getLastRequeryTask() {
return lastRequeryTask;
}
@Override
protected void bindParametersForCollection(QueryCollection queryCollection,
Object[] object,
PreparedStatement preparedStatement) throws SQLException {
super.bindParametersForCollection(queryCollection, object, preparedStatement);
if (queryCollection != null) {
lastRequeryTask = System.currentTimeMillis();
}
System.out.println("Re-execute "+(queryCollection == null?"count ":"")+"query for VO "+getName());
}

@Override
protected void processDatabaseChangeNotification(QueryCollection queryCollection) {
System.out.println("*** TaskViewImpl DatabaseChangeNotification");
lastRequeryTask = System.currentTimeMillis();
super.processDatabaseChangeNotification(queryCollection);
}

Step 8. Add the following code after the constructor in SubtaskViewImpl.

long lastRequerySubTask = 0;
public long getLastRequerySubTask() {
System.out.println("SubtaskViewImpl: getLastRequerySubTask() returns " + lastRequerySubTask);
return lastRequerySubTask;
}
@Override
protected void bindParametersForCollection(QueryCollection queryCollection,
Object[] object,
PreparedStatement preparedStatement) throws SQLException {
super.bindParametersForCollection(queryCollection, object, preparedStatement);
if (queryCollection != null) {
lastRequerySubTask = System.currentTimeMillis();
System.out.println("SubtaskViewImpl: bindParametersForCollection() set lastRequerySubTask to " + lastRequerySubTask);
}
System.out.println("Re-execute "+(queryCollection == null?"count ":"")+"query for VO "+getName());
}

@Override
protected void processDatabaseChangeNotification(QueryCollection queryCollection) {
System.out.println("*** TaskViewImpl DatabaseChangeNotification");
lastRequerySubTask = System.currentTimeMillis();
System.out.println("SubtaskViewImpl: processDatabaseChangeNotification() set lastRequerySubTask to " + lastRequerySubTask);

super.processDatabaseChangeNotification(queryCollection);
}

Step 9. Expose both methods via the Client Interfaces

Step 10. Create a new JSPX page - MyGantt.jspx with Managed Bean

Step 11. You should have the following in your Data Control Palette



Step 12. Drop the SubTaskView1 DataControl as a Read Only Table on the page

Step 13. Drop the SubTaskView1 DataControl as a Read Only Table on the page

In the Table properties set content delivery = immediate

Step 14. Drop the method getLastRequerySubtask() as an ADF button above the table
We do this to get the method binding. Later we will delete the button.

Step 15. Add a Poll control to the page
The poll control will contact the middle tier ViewObject every 2 seconds to see if it has received database notifications.

Step 16. Add the following Poll logic to the managed bean

public void onPollTimerExpired(PollEvent pollEvent) {
Long lastRequerySubTask = (Long)AdfFacesContext.getCurrentInstance().getViewScope().get("lastRequerySubTask");
Long lastRequerySubTaskFromVO = (Long)BindingContext.getCurrent().getCurrentBindingsEntry().getOperationBinding("getLastRequerySubTask").execute();
System.out.println("+++++ Sub Task Timer expired: lastRequerySubTask = "+lastRequerySubTask+", lastRequerySubTaskFromVO = "+lastRequerySubTaskFromVO);
if (lastRequerySubTask == null || (!lastRequerySubTask.equals(lastRequerySubTaskFromVO))) {
AdfFacesContext.getCurrentInstance().getViewScope().put("lastRequerySubTask",lastRequerySubTaskFromVO);
AdfFacesContext.getCurrentInstance().addPartialTarget(getT1());

System.out.println("++++ Data requeried in VO. PPR'ing the table");
}
}

Set the poll control properties as follows -



Step 17. Test

Add a couple of rows to the DB tables -

delete from subtask;
delete from task;
commit;

insert into task values ('Task 1', 'Task Nr 1', sysdate, sysdate + 10);
insert into subtask values ('SUBTask 1', 'SUBTask Nr 1', sysdate, sysdate + 5, 'Task 1');
insert into subtask values ('SUBTask 2', 'SUBTask Nr 2', sysdate+5, sysdate + 10, 'Task 1');
commit;

Run the page

You should see the following -




Now add a new row to the table via SQLPLUS -

insert into subtask values ('SUBTask 3', 'SUBTask Nr 3', sysdate+5, sysdate + 10, 'Task 1');
commit;

The table should auto-refresh.

So Auto-Refresh is working fine for the table, so let's apply the same logic to the Gantt Project control.

Step 18. Add a Gantt Project Control to the page

Drag and Drop TaskView1 as a Gantt Project Control above the table control (use the Structure panel for this)

Set Task Id = TaskId
Start Time = Start Date
End Time = End Date

Click on the Subtasks tab -

For Subtasks Accessor select the View SubTask4Gantt
Set Sub Task Id = TaskId
Start Time = Start Date
End Time = End Date

Step 19. Drop the method getLastRequeryTask() as an ADF button above the Gantt control
We do this to get the method binding. Later we will delete the button.

Step 20. Add another poll control which will call this method via backing bean method
We do this to get the method binding. Later we will delete the button.

Your structure panel should look something like this -



Step 21. Add the following method to the backing bean for polling on Task changes

public void onPollTimerExpired1(PollEvent pollEvent) {
Long lastRequeryTask = (Long)AdfFacesContext.getCurrentInstance().getViewScope().get("lastRequeryTask");
Long lastRequeryTaskFromVO = (Long)BindingContext.getCurrent().getCurrentBindingsEntry().getOperationBinding("getLastRequeryTask").execute();
System.out.println("*** Task Timer expired: lastRequeryTask = "+lastRequeryTask+", lastRequeryTaskFromVO = "+lastRequeryTaskFromVO);
if (lastRequeryTask == null || (!lastRequeryTask.equals(lastRequeryTaskFromVO))) {
AdfFacesContext.getCurrentInstance().getViewScope().put("lastRequeryTask",lastRequeryTaskFromVO);
AdfFacesContext.getCurrentInstance().addPartialTarget(getPg1());
System.out.println("**** Data requeried in VO. PPR'ing the gantt");
}

Also add this line of code to the method onPollTimerExpired to PPR on the Gannt as well

AdfFacesContext.getCurrentInstance().addPartialTarget(getPg1());

Step 22. Set the 2nd poll control properties as follows -


Step 23. set Databinding.cpx to use Shared AppModule



Step 24. Run the Page

Set up test data -

delete from subtask;
delete from task;
commit;

insert into task values ('Task 1', 'Task Nr 1', sysdate, sysdate + 10);
insert into subtask values ('SUBTask 1', 'SUBTask Nr 1', sysdate, sysdate + 5, 'Task 1');
insert into subtask values ('SUBTask 2', 'SUBTask Nr 2', sysdate+5, sysdate + 10, 'Task 1');
commit;

View the control and open to see the subtasks -




Add a new Subtask via SQLPLUS
insert into subtask values ('SUBTask 3', 'SUBTask Nr 3', sysdate+5, sysdate + 10, 'Task 1');
commit;

The Gantt chart will auto-refresh.

Add a new Task via SQLPLUS

insert into task values ('Task 2', 'Task Nr 2', sysdate, sysdate + 10);
commit;

The Gantt chart will auto-refresh.

25. Cleanup the app
We only need 1 poll control and 1 managed bean onPollTimerExpired method.
So include the code from onPollTimerExpired1() in onPollTimerExpired().
Delete the second poll control.

I only use the table control here because I have some issues with auto-refresh on the SubTask4Gantt view. All we really need is the iterator SubtaskView1Iterator and
the following code -

In SubtaskViewImpl -
public void executeTheQuery(){
ViewObject vo = this.getViewObject();
vo.executeQuery();
}
expose this method thru the client interface.

drop this method as a Button on the page and double-click to generate
the code in the backing bean -

public String executeTheQuery_action() {
BindingContainer bindings = getBindings();
OperationBinding operationBinding = bindings.getOperationBinding("executeTheQuery");
Object result = operationBinding.execute();
if (!operationBinding.getErrors().isEmpty()) {
return null;
}
return null;
}

We can call this method as the page is being instantiated.

So now we can delete the table control.

Why do I need the 2nd SubTask Iterator?
Essentially we shouldn't need this, I just had issues getting the database notification to work with the subtaskView in the Gantt. This my workaround of creating the 2nd iterator "independent" of the Gantt.

In a further post I will hopefully be able to report on what was causing this issue
and how I fixed it!




SQL for Table Creation

Use Oracle DB 11g
activate database notification for schema owner

CREATE TABLE TASK
(
TASK_ID VARCHAR2(10 BYTE) NOT NULL,
TASK_NAME VARCHAR2(20 BYTE) NOT NULL,
START_DATE DATE NOT NULL,
END_DATE DATE
, CONSTRAINT TASK_PK PRIMARY KEY
(
TASK_ID
)
ENABLE
)
;
CREATE TABLE SUBTASK
(
SUBTASK_ID VARCHAR2(10 BYTE) NOT NULL,
SUBTASK_NAME VARCHAR2(20 BYTE) NOT NULL,
START_DATE DATE NOT NULL,
END_DATE DATE,
TASK_ID VARCHAR2(10 BYTE) NOT NULL
, CONSTRAINT SUBTASK_PK PRIMARY KEY
(
SUBTASK_ID
)
ENABLE
)
;
ALTER TABLE SUBTASK
ADD CONSTRAINT SUBTASK_TASK_FK1 FOREIGN KEY
(
TASK_ID
)
REFERENCES TASK
(
TASK_ID
)
ENABLE
;