Wednesday, June 10, 2009

Migrating Portal Repository with change in DN

Another in a long line of very esoteric issues...

If you are migrating a portal repository, possibly from Production back into Dev or vice versa you may run into the following error when running ptlconfig

STEP 1 : Populating Portal seed in OID
Connected.
Creating Lightweight User Accounts and Groups in OID
Portal schema version is: 10.1.2.0.2
Error code : -6502
Error message: ORA-06502: PL/SQL: numeric or value error
ERROR: creating lightweight users and groups in OID ... exiting

PL/SQL procedure successfully completed.

This happens if you have changed the base dn of your OID. For example, you might have had a dn of dc=concept2completion,dc=net
and then decided to change to dot com
dc=concept2completion,dc=com

or possibly you removed a sub-domain
dc=chicago,dc=concept2completion,dc=net
changed to
dc=concept2completion,dc=net

In either case, you will get the error listed above. The problem is that the script secoidd.sql relies on the dn stored in the table wwsub_model$. Below is an extract of secoidd.sql

if l_subscriber_dn is null then
-- The control should never reach here as the subscriber DN
-- should be available in the wwsub_model$ table.
So, if you get into this position, you will need to update the value in the dn column of wwsub_model$.

Seems like such a simple solution. So simple that I have now gone to the process of figuring it out three times.

Monday, June 08, 2009

SQL for Date Spanned Data

I was recently presented with a sql challenge. Although I came up with something that works, I'm not convinced it is the best solution. This is a very long post that is mostly question, but possibly a helpful example. The details are below.

I was given a table with the following columns
ID -- Primary Key
DIVISION -- Identifier of a Division
START_DATE -- Date when the Division starts
END_DATE -- Date when the Division ends

If you want to try this yourself, I added all the create statements and sample data creation to the end of this note.

The data has an implicit concept of a "span." A Division may have many spans. The start date of a new span is typically one day after the end date of the previous span. In this case a Division has a contiguous span. Spans never overlap; that is, a single division never has a row with a start date between the start and end date of another row of the same division (and never has an end date between the start and end of another row of the same division).

Below is some sample data:

Id, Division, Start_date, End_date

10 1 09-JUN-2009 10-JUN-2009
11 1 11-JUN-2009 12-JUN-2009
12 1 13-JUN-2009 14-JUN-2009 -- Note the following row is not contiguous
14 1 17-JUN-2009 18-JUN-2009
15 1 19-JUN-2009 20-JUN-2009


If this were the total data set then Division 1 would have 5 spans, but only two contiguous spans (09 - 14 Jun and 17 - 20 Jun).

The challenge was to create a sql statement to only return contiguous spans by division. I immediately thought of a CONNECT BY but the challenge was to determine the START WITH condition.

[Update: In response to this post Alex Nuijten came up with a better method than any described below. Take a look here:
http://nuijten.blogspot.com/2009/06/analytic-function-finding-gaps.html ]
I came up with two ways to do this. I'm still not certain if there is a better solution. The first is far better and uses some SQL analytics to determine the START WITH condition. If you were to use a WHERE clause, it should go in the WITH section as identified. My example is below.

with span_info as (select s.division, s.start_date, s.end_date
, (s.start_date -lag(end_date, 1) over (partition by s.division order by start_date)) new_span
-- null or > 1 indicates a new contiguous span
, (lead(start_date, 1) over (partition by s.division order by start_date) - s.end_date) end_span
-- the end_span is not needed, just left for example
-- null or > 1 indicates the end of a contiguous span
from spantest s
-- a WHERE clause would go HERE, not in the main SELECT below
order by 1, 2 )
select division
, connect_by_root start_date span_start -- start of a contiguous span
-- , start_date -- start of the last span of a contiguous span
, end_date -- end of the contiguous span
-- , new_span, end_span, connect_by_isleaf
from span_info
where connect_by_isleaf = 1
-- gets only "leaf" recodes, i.e. the end of a contiguous span
start with nvl(new_span,1000) > 1
-- gets beginning of a contiguous span
connect by
prior end_date + 1 = start_date
-- connects spans, the 1 here and in the "start with" can be changed together
and prior division = division
-- ensures spans are for the same division
order by 1, 2

My second idea is to use an exists command to determine if the the first there exists a row with an end_date equal to start_date - 1 for the division. I can write the statement, but I'm not sure how to get the combination of the DIVISION and the START_DATE in to the START WITH. I could do some concatenation, but I don't like that at all. The code is below, but DO NOT RUN THE QUERY; it is very slow.

-- ************ DO NOT RUN THIS QUERY
select division
, connect_by_root start_date span_start -- start of a contiguous span
-- , start_date -- start of the last span of a contiguous span
, end_date -- end of the contiguous span
-- , new_span, end_span, connect_by_isleaf
from spantest
where connect_by_isleaf = 1
-- gets only "leaf" recodes, i.e. the end of a contiguous span
start with to_char(start_date,'yyyymmdd') ||'~' || division in
(select to_char(st2.start_date,'yyyymmdd') ||'~' || st2.division
from spantest st2
where not exists
(select 1 from spantest st3
where st3.division = st2.division
and st3.end_date = st2.start_date + 1
and st3.id != st2.id)
)
-- gets beginning of a contiguous span
connect by
prior end_date + 1 = start_date
-- connects spans, the 1 here and in the "start with" can be changed together
and prior division = division
-- ensures spans are for the same division
order by 1, 2


This is a lot of code and no-one other than me may ever read it. If you do, though, and have other ideas, I would love to hear them.

-- ********* Create Statements and sample data

CREATE TABLE "SPANTEST"
( "ID" NUMBER NOT NULL ENABLE,
"DIVISION" NUMBER NOT NULL ENABLE,
"START_DATE" DATE NOT NULL ENABLE,
"END_DATE" DATE NOT NULL ENABLE,
CONSTRAINT "SPANTEST_PK" PRIMARY KEY ("ID") ENABLE
)
/

CREATE INDEX "SPANTEST_IDX3" ON "SPANTEST" ("END_DATE")
/
CREATE INDEX "SPANTEST_IDX2" ON "SPANTEST" ("START_DATE")
/
CREATE INDEX "SPANTEST_IDX1" ON "SPANTEST" ("DIVISION")
/

CREATE SEQUENCE "SPANTEST_SEQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1441 CACHE 20 NOORDER NOCYCLE
/

CREATE OR REPLACE TRIGGER "BI_SPANTEST"
before insert on "SPANTEST"
for each row
begin
if :NEW."ID" is null then
select "SPANTEST_SEQ".nextval into :NEW."ID" from dual;
end if;
end;

/
ALTER TRIGGER "BI_SPANTEST" ENABLE
/


-- create sample data for 10 Divisions
begin
for i in 1..20 loop
insert into spantest (division, start_date, end_date)
select 1, trunc(sysdate + (rownum*2 - 1)),trunc(sysdate + (rownum*2)) from all_tables;
end loop;
end;
/

-- create span gaps on the 15th of each month
delete from spantest where
to_char(start_date,'dd') = '15'
/

Wednesday, May 06, 2009

Locating a Corrupt PDF (or many types of corrupt files) in a BLOB

I recently had a client pose the following question to me.
We have a system that generates pdf's based upon data from our Oracle database. The pdf's are then stored in a BLOB column in a table. We recently realized that at least one of those pdf's was corrupt. Is there a way within Oracle to determine if others are corrupt?

I initially thought about trying to write a script that would pull each blob, run it through some kind of pdf validator and write a log entry if it were bad. Hmmm, use plsql and call out to a validator on the O/S? Write a java routine to do the same thing? What validator would I use?

Then I had an idea--Oracle Text (formerly Intermedia and Context). I could create a context index on the blob column and see if there are any errors.

CREATE INDEX myIndex ON my_table(my_blob) INDEXTYPE IS ctxsys.context;

If the Oracle Text engine is unable to index the blob it writes a log entry to the view ctx_user_index_errors including the rowid. Depending on the database version you might have issues with very recent versions of the pdf, but that was not an issue in our case as every pdf was created by the same pdf generator.

I think Oracle Text is underused. This is just one more example of how to make it work for you.

Saturday, May 02, 2009

Oracle SQL Delimiter

It's been a while since I made a real post, one that has some technical merit. This one just barely qualifies.

There is a nice classic report type "Function Returning a SQL Query" which allows you to write a block of code that returns a select statement. That select statement is the basis for the report. I often use it to simplify building a where clause. It might look something like this:

declare
l_q varchar2(32767); -- This is the return variable. It will hold a select statement

begin
l_q := 'select d.name department, e.name employee
from dept d, emp e
where d.deptno = e.deptno ';

if :P1_DEPTNO is not null then
l_q := l_q || ' and d.deptno = :P1_DEPTNO ';
end if;

-- insert more if statements like above

return l_q;
end;


With Interactive Reports this has become less likely, but it still happens.

Sometimes, though, the query is a bit more complicated, something like this:

begin
l_q := 'select d.name department, e.name employee,
to_date(to_char(e.hiredate,''yyyymm'' ||''01''),''yyyymmdd'') first_day_of_month
from dept d, emp e
where d.deptno = e.deptno
and e.status in (''NEW'', ''PENDING'', ''FOO'')
and d.status = ''NEW'' ';

if :P1_DEPTNO is not null then
l_q := l_q || ' and d.deptno = :P1_DEPTNO ';
end if;

-- insert more if statements like above

return l_q;
end;


You get the idea, a lot of strings and a lot of double ticks (''). There is an easier way, though: a custom SQL Delimiter. Usually a single tick (') indicates the start of a string. If you use a tick within it, you need two ticks ('') to escape it (see code above). But you can avoid that with a custom delimiter. You turn it on with q', that's all, just the letter q followed by a tick. The trick is that the very next character is the delimiter, and a few are special. You end the statement with followed by a tick. Examples are the easiest, so here are a few:

1. l_q := q'! I don't need to escape the ' in the word don't !';
In this case the ! is the special character. q'! starts the string and !' ends it.

2. l_q = q'{ I don't need to escape the ' in the word don't }';
This is a little different. If your special character is { then you use }' to turn it off. It is pretty obvious which are special: [], {}, <>.

So, the code above becomes:

begin
l_q := q'{ select d.name department, e.name employee,
to_date(to_char(e.hiredate,'yyyymm' ||'01'),'yyyymmdd') first_day_of_month
from dept d, emp e
where d.deptno = e.deptno
and e.status in ('NEW', 'PENDING', 'FOO')
and d.status = 'NEW' }';

if :P1_DEPTNO is not null then
l_q := l_q || ' and d.deptno = :P1_DEPTNO ';
end if;

-- insert more if statements like above

return l_q;
end;


You can use this just about anywhere in sql or pl/sql where you want a string.

Friday, April 10, 2009

What is this?




First, I apologize, this is my third post in a row that is not technical. I promise I will get back to the real purpose of this blog in my next post.

Now, on to the question. Does anyone recognize this device? I found it in my closet the other morning. I suspect I probably took it out of a bag after a trip, or picked it up instead of stepping on it in one of my kids' rooms. I probably knew what it was at the time, probably thought I would stick it there for a few days and deal with it later. Now it is later, though, and I have no idea what it is or where it came from.

It takes 3 AAA batteries. It has no identifying markings of any kind. Inside the battery compartment there is no writing. When I turn it on it makes a very high pitched, very low volume whining noise. There is nothing on the sides that are not shown in the two images above. You now know as much as I do about this thing.

If you know what this is, really know what it is, please post a comment. Thanks.

Update: We have a winner! I won't publish the answer here, in case you want to guess. Check out the comments for the answer.

Thursday, April 09, 2009

Going Viral


This is a chart of traffic on http://www.crapmanagement.com
As you can see, yesterday crapmanagement "went viral," more than doubling its former high (which was mostly me testing the web logging capabilities).

Wednesday, March 25, 2009

Oracle Portal and APEX RSS Feeds and Traffic Analysis

I try to avoid advertising in this blog, but I'm going to break that rule as I have had a few inquiries lately on these topics. C2 has new product offerings that provide RSS feeds for Oracle Portal and APEX. For details, contact C2. C2 also has a web traffic capture and reporting tool. This tool can be used on any site, but has a few specific capabilities related to Oracle Portal and Application Express. Again, for details, contact C2.

And just an update on my last post -- the fine folks on the APEX team released patch 833890 to solve this import issue. You can get the patch at http://metalink.oracle.com.

Wednesday, March 11, 2009

APEX 3.2 Gives Error on Import - ERR-3331

Just a quick note regarding the 3.2 import process... APEX added a number of enhancements and checks during the import of an application. The downside is that these introduced some negative performance characteristics. If you are importing a medium to large size app you are likely to get either a timeout or an error message:
ERR-3331 This page was already submitted and can not be re-submitted.

Oracle has confirmed the problem and a fix is in the works. I'll update this post when the patch is available.

The good news is that the application will import anyway. After you get the error, just go back to the builder and check to make sure the import was successful.

25-Mar-2009: More good news -- the fine folks on the APEX team released patch 833890 to solve this issue. You can get the patch at http://metalink.oracle.com.

Monday, March 09, 2009

APEX 3.2 - save state before branching

Just a quick note about a little known new feature in APEX 3.2: save state before branching. When creating a branch and setting items with values, you now have the option to either pass those values in the URL or to have APEX set them into session state prior to doing the branch.

Thursday, March 05, 2009

Application Express (APEX) 3.2

We went through the upgrade to 3.2 last night and it was very smooth. We had a couple minor challenges but that is because of our unique environment.

1. We have an SSO configuration. APEX does not specify the owner of the package wwv_flow_custom_auth_sso when it generates the return link for SSO. This means that the APEX_PUBLIC_USER (or whatever user your DAD is configured to use) must have a synonym to wwv_flow_custom_auth_sso. You can also create a public synonym so long as one does not exist for another application.

2. I noticed that some of our custom stylesheets give a slightly different look with date picker items. This may be due to a change in the way APEX 3.2 generates date pickers. I'll look into it and post anything I find.

3. Apex has a new database schema. It has finally moved to APEX_030200. [ removed a comment about the version that was wrong... thanks Patrick! ]

A very easy install, really. Thanks to the APEX team once again!

Friday, January 16, 2009

APEX - Application Express 3.2, More than a Forms Conversion Release

Application Express 3.2 has been advertised as a Forms Conversion release, but I've recently been looking over an additional category of enhancements that are due to be in the next early adopters release. It probably comes as not surprise to those who know me that the category is security. Below is a partial list of the enhancements as I understand them. Once I get my hands on the EA release I'll provide more significant commentary, but I like what I see so far.


Declarative authentication timeouts by session length and idle time

Only allow a developer to stay logged into the APEX builder for a specified period of time or time spent idle. This is handled server side, so just hacking the local cookie won't bypass the timeout--nice!

HTML Form settings for Password pages (autocomplete=off)
Does what it says.

Reduced privilege of APEX schema
No change to functionality, or really even to security as long as your FLOWS_xxx schema is secure, but any time you can skinny down privs to the minimum required it closes the possibility of a loophole.


Database monitoring disabled by default

Seems to make sense.

Declarative session state encryption
Now this makes great sense. APEX has a reasonably good security model in place to protect session state information, but we all know where session state is stored, in a single table in the FLOWS_XXX schema. I've never liked the idea that my SSN make hang out in that table for some DBA to look at, or possibly have some rogue developer write some hidden page that let's them go peek at my session state. Allowing a developer to indicate that an item be encrypted when saved in the database without having to worry about encrypting and decrypting the item greatly reduces the developer's burden--or more likely, means it will actually happen.

New Password item types that do not save state
In short, never persist this password data into the APEX sessions state table. I love the idea, though I wonder if a checkbox giving all items this option might not be better. We'll see how this turns out . . .

Ability to specify HTTPS for the APEX instance
In short, only allow the APEX builder to run when the browser is communicating via HTTPS.

OK, so how about one feature that is not on the list? Who would like a "Scratch" item type--an item that is never rendered, never posted and not settable on the URL? It would just be a place to store session state, somewhat like an application item that has session state protection enabled, but the item is on a page. Let me know what you think.

Friday, December 05, 2008

Oracle Application Express (APEX): Three Kinds of Session State

One of the best features of APEX is its ability to manage session state for you. One of the trickiest things you run in to when getting in to advanced development, though, is understanding just when session state is updated and when it is persisted. The easiest way I can describe this is with some examples:

1. PERSISTED Session State
Most of the time you will be dealing with persisted session state--session state that resides within the database and that is available from subsequent page requests. Any time you set an item's value with a computation or process you get PERSISTED session state. If you pass an item and value on the URL you get PERSISTED session state. If you submit a page with a text item (or radiobox, checkbox, select list, hidden item, etc.) the item will get persisted session state.

That seems like most of the ways you set item session state, but there are a couple of other ways.

2. IN MEMORY Session State (IMSS)
This category really falls in to two parts: Item Rendering and Automated Row Fetch
So . . .

2A. Item Rendering
You can set item attributes of Source and Default. Let's say we set an text item (P2_VALUE10) to have default value to C2C. Run the page and you will see an item on the page with C2C in a text box. Check the session state (use the Session link at the bottom of the page) and you will find that P2_VALUE10 does not have any session state. How is this possible? It's right there on the page with C2C, right?

The value C2C was set IN MEMORY session state. It disappears immediately when the page is done rendering; it is not saved in the database. This is not usually an issue, because you are probably going to submit the page, in which case (according to point 1 above) it will store as PERSISTED session state.

A special note on item rendering in memory session state (IRIMSS :) ): IRIMSS happens as the item is rendered. Say you have 20 items on the page, with the tenth item, P2_VALUE10, having default value of C2C. If you have any computations or conditions inside of items 1..9 that depend on P2_VALUE10, it will not have the default value. For example, say P2_VALUE3 has a display condition: Display when P2_VALUE10 = C2C. P2_VALUE3 will not show. Items 11..20, though, will see P2_VALUE10 = C2C. It can be a bit confusing.

2B. Automated Row Fetch (ARF)
Using ARF produces IN MEMORY session state as described above, with a little twist. The ARF process allows you to choose whether to put the value of the item values into IMSS right when the process is run, or as the items are rendered. In early versions of APEX it always happened as the items were rendered. In recent versions the default is to put the value into IMSS when the ARF process runs.

Why Does It Matter
Why does it matter if it is PERSISTED Session State or IMSS? I have found many cases where IMSS caused confusion and bugs. A good example is breadcrumbs. Say we have a department report, which drills in to a department form, which in turn drills in to an employee form. You could have a breadcrumb like this:

Dept Report > Dept Form > Employee

But that is not very enlightening. Wouldn't it be better to have the following?

Dept Report > Accounting > Nielsen

Which means you would define something like this

Dept Report > &P2_DNAME. > &P3_LAST_NAME.

If you used ARF to set P2_DNAME, however, but did not submit page 2, instead clicking on an employee link, P2_DNAME will be null on the employee page, resulting in the following breadcrumb:

Dept Report > > Nielsen

There are many other similar scenarios. But, the underlying cause is IMSS.

If you need persisted session state, just do your own fetch process or computation. You can leave the ARF process if you want, it won't hurt to have both.

I hope this sheds a little light on APEX session state.

Thursday, December 04, 2008

Oracle Portal and Oracle BI Publisher

If you are using Oracle Portal and are used to using the Portal Forms Builder, you may want to create parameter forms for your BI reports in the Portal Forms Builder. This article provides a methodology for generating and redirecting to the BI Publisher URL from a Portal Form.

Step 1: Create a package that will do the redirect for you given the appropriate parameters.

--
--
create or replace
package bip1 as
g_url varchar2(32767);

-- add additional parameters as required
procedure bip_r
(
p_xf IN VARCHAR2 DEFAULT NULL,
p_custom1name IN VARCHAR2 DEFAULT NULL,
p_custom1val IN VARCHAR2 DEFAULT NULL,
p_custom2name IN VARCHAR2 DEFAULT NULL,
p_custom2val IN VARCHAR2 DEFAULT NULL);
end;
/

--
create or replace
package body bip1 as

procedure bip_r
(
p_xf IN VARCHAR2 DEFAULT NULL,
p_custom1name IN VARCHAR2 DEFAULT NULL,
p_custom1val IN VARCHAR2 DEFAULT NULL,
p_custom2name IN VARCHAR2 DEFAULT NULL,
p_custom2val IN VARCHAR2 DEFAULT NULL)
as
-- for information on determining the URL below, see
-- http://blogs.oracle.com/xmlpublisher/2006/07/accessing_xmlp_enterprise_repo.html
l_url varchar2(32767) := 'http://[Your_BIP_Server]:9704/xmlpserver/[your_folder]/[your_report]/[your_report].xdo?_xpf=&_xpt=1&...';
begin
l_url := l_url || '&_xf=' || p_xf || '&'
|| p_custom1name || '=' || p_custom1val || '&'
|| p_custom2name || '=' || p_custom2val ;

bip1.g_url := l_url;
end;
end;
/


Step 2: Create a Portal Form against a procedure and choose the bip1.bip_r procedure.

Step 3: Modify the Portal Form

a. p_xf is the allowable output formats: html, pdf, csv, etc.
b. p_custom1name (and all p_custom#name items) should be hidden and should be the name of your BI Publisher report variables
c. p_custom1val (and all p_custom#val items) are the values you want your users to enter, associated with the corresponding p_custom#name
d. At the Portal Form level, where you see the text area following
On successful submission of a form, execute this PL/SQL block or PL/SQL procedure:
Hint:
You can redirect your browser to a PL/SQL procedure, for example a procedure that creates a Web page, using either of these methods:

1. call('', '');
Redirects the browser to the procedure and passes a parameter containing the URL back to the form.
2. go('');
Redirects the browser to the procedure but does not pass a URL to return to the form.


Enter: go(bip1.g_url);


Running this form will redirect you to the correct BI Publisher URL.

Monday, November 10, 2008

Haiku

One of the last times I hung out with Carl Backstrom we talked about texting someone a haiku. It's not much, but the occasional blog post in Carl's memory can't be a bad thing. I offer this:

Dynamic
CarlBack blogs now fixed
Early Night

I invite you to post your own haiku.

Tuesday, October 28, 2008

Carl Backstrom

Many have already posted about the tragic loss to the APEX development team and community. I feel the need to add my own short tribute--though it will certainly take me time to collect my thoughts. For now, simply, "We already miss you, Carl."

Anton

Thursday, September 11, 2008

Oracle Application Server Portal, Application Express (APEX) and OID

We have done a lot of work at C2 over the past few years integrating Portal with APEX (security and themes/ui), APEX with OID/SSO, OID with MS Active Directory (AD), APEX with AD, APEX with SSL LDAP . . . Well, you get the idea. We finally put this experience into a couple of training modules. If you are interested in these topics, click on the C2 Consulting logo at the right.

We have done similar work with all of the above and Oracle Universal Content Management (UCM) but have not integrated that into the course. Let me know if you think that would be worthwhile.

Friday, August 29, 2008

Oracle Application Express (APEX) "submit" Button

We just ran in to the strangest problem. All of our buttons and standard tabs stopped working on a particular page. Parent tabs worked fine, but anything that relied on posting the page (javascript:doSubmit) stopped working. Neelesh Shah came up with the solution. One of our buttons was "submit"--all lower case. Usually a submit button in APEX is either SUBMIT of Submit, with at least one upper case letter. APEX automatically adds an id="" to all the buttons. As it turns out, id="submit" (all lower case) causes browsers to stop submitting (posting) pages. Just changes the value to Submit did the trick.

Friday, August 22, 2008

Oracle Internet Directory (IDM OID) patchset 10.1.4.2 and WNA

Ouch! We recently installed the OID 10.1.4.2 patch to solve some issues with Server Chaining to Microsoft Active Directory (MS AD). There were two object classes that did not get mapped for groups and there were problems that OID would not find any group that was not directly in the dn that was chained to AD. If you chained
cn=ad,cn=groups,dc=mycompany,dc=com
to
cn=groups,ou=myDept,dc=mycompany,dc=com
but you had a group in subcontainer
cn=anotherLevel,cn=ad,cn=groups,dc=mycompany,dc=com
OID would not find it.

The patch almost worked as expected--we got one of the two object classes promised and we could find the groups in subcontainers. Unfortunately the patchset broke Windows Native Authentication (WNA). The problem is that the patch introduced a new java JDK, version 1.4.2._14. After many hours of troubleshooting we found Oracle bug 6658334--WNA FAILS AFTER APPLYING IDM 10.1.4.2.0 PATCHSET. The solution appears to be to downgrade the Sun JDK to 1.4.2_13. We did this and it works, but oh what a headache.

You might get an error stack that looks like this:

DAS servlet init enter
oiddas: Release 10.1.4.0.1 Production Started
<$ORACLE_HOME>/j2ee/OC4J_SECURITY/applications/oiddas/ui/WEB-INF/lib/oiddas.jar archive
DAS servlet init exit
Getting creds for HTTP/ ...
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null KeyTab is
<$ORACLE_HOME>/j2ee/OC4J_SECURITY/config/sso.keytab refreshKrb5Config is
false principal is HTTP/ tryFirstPass is false
useFirstPass is false storePass is false clearPass is false
principal's key obtained from the keytab
principal is HTTP/
KerberosAuthenticator: GSSException raised in constructor -
No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT
credentials failed!)
GSSException: No valid credentials provided (Mechanism
level: Attempt to obtain new ACCEPT credentials failed!)
at
sun.security.jgss.krb5.Krb5AcceptCredential.getKeyFromSubject(Krb5AcceptCreden
tial.java:189)
at
sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.j
ava:80)
. . .
30 Caused by: javax.security.auth.login.LoginException:
java.lang.NullPointerException
at java.lang.StringBuffer.append(StringBuffer.java:467)
at
com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginMo
dule.java:576)
at
com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:475)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Wednesday, August 13, 2008

Oracle Open World (Oracle OpenWorld)

I will be speaking at OOW this year on two topics.

How to Hack an Oracle Application Express Application

If you write HTML applications in any technology and you care about your data, this presentation is for you. All HTML applications share some attributes that expose them to potential hacking. APEX has many features that will allow developers to lock down their applications – or to expose them to hacking. I will show techniques that can be used to hack HTML applications, how to close these holes within APEX and where APEX may expose these holes through its wizards. Naturally, I will show how to protect against any hack that I demonstrate. This session can benefit the novice to the highly advanced APEX developer as well as developers of any HTML application.

This is a skinnied down version of the module that C2 Consulting teaches in its Application Express classes.

Realizing ROI with Application Express

As part of Massachusetts healthcare reform, C2 Consulting worked with Harvard Pilgrim Healthcare (HPHC) to develop a new business process for providing health insurance directly to the subscriber. Utilizing Oracle Application Express, the HPHC system allows individuals to apply, enroll and be confirmed in a healthcare plan online in just a few minutes. Developed in just one month, the project cost will be recovered in just one year's saved postage.

Oracle Portal Secure Content Repository Views

I recently went searching for the documentation on the Oracle Portal repository views for Portal 10.1.4 and had a hard time finding them.

The Views
http://www.oracle.com/technology/products/ias/portal/html/plsqldoc/pldoc1014/wwsbr_api_view.html

The APIs
http://www.oracle.com/technology/products/ias/portal/html/plsqldoc/pldoc1014/summary.html

The Documentation
http://download-west.oracle.com/docs/cd/B14099_19/portal.1012/b14134/toc.htm

And More Documentation
http://download.oracle.com/docs/cd/B14099_15/portal.1014/b14135/pdg_part3.htm#sthref1557

Monday, August 04, 2008

Advanced Configuration Training Course: Oracle Application Express (APEX)

This is just a quick note to mention that C2 Consulting has added a new module to its Oracle Application Express (APEX) course. The training class is modular, so class attendees or clients can choose which modules are taught during a particular session. The new Advanced Configurations course covers installation and configuration in a variety of environments. Some of the topics follow:

  • High Availability, RAC, HA Middle Tiers (I contributed to the Oracle white paper on this topic)
  • Configuring Apache for SSL
  • Configuring Apache Virtual Hosts
  • Using Apache 2.x as a reverse proxy
  • Using Oracle Web Cache
  • Capturing IP Address behind Firewalls, Reverse Proxies and Web Cache
  • Using Apache Rewrite Rules
  • Custom DAD configurations--passing environment variables, setting default application, etc.
  • Custom Authentication and Authorization Schemes
  • How to enable Oracle Single Sign-On (SSO)
  • How to integrate with Netegrity (Computer Associates) Siteminder (Optional)
  • How to integrate with RSA (Optional)
  • How to integrate with PKI (client-side) certificates (Optional)
If you are interested in this topic or any of the C2 courses, contact C2.