Wednesday Jun 20, 2012

JDeveloper does not recognize existing subversion working directory

Just a quick note about an issue where JDeveloper no longer recognized an existing
subversion working directory.

Symptom: 

JDeveloper Versioning menu offers to Version an Application that is already versioned in svn.


Jdev_svn


Cause:

The repository url contained in the hidden .svn folders of the working directory is no longer valid.

Solution:

Determine the correct url for the Subversion repository and update the .svn working directory.
Fix the url contained in the svn folders of the working directory using the svn switch command.

Example:

          In a shell change directory to the Application folder.

          Run the svn info command to confirm the current settings.

               $ svn info
                  Path: .
                  URL: http://192.168.1.128/repos/jdeveloperrepo/AsyncExamples/BPELCallAsync/trunk
                  Repository Root: http://192.168.1.128/repos/jdeveloperrepo
                  Repository UUID: 3dc5eb88-3001-0010-8d6e-fd6f73825647
                  Revision: 145
                  Node Kind: directory
                  Schedule: normal
                  Last Changed Rev: 145
                  Last Changed Date: 2012-06-07 07:15:56 -0700 (Thu, 07 Jun 2012)

           In this case, the IP address in the repository URL is incorrect,
           the svn server is located at 192.168.56.1
           Note: The IP Address currently set is displayed after the Project Name in the
           Application Navigator.  See the screen snapshot above.


           Run the svn switch command with the --relocate option
           Provide as much of the urls as necessary to correctly rewrite the url from current to new.
           For example,
           to change the repository server address from 192.168.1.128   to   192.168.56.1

                    $  svn switch --relocate  http://192.168.1.128   http://192.168.56.1  .

                              (Note the trailing period in the above command)

          When the url is correct, JDeveloper should recognize the Subversion Working Directory.

Wednesday May 02, 2012

Making sequential calls using Oracle Mediator

Many people are unaware that Oracle mediator can be configured to make sequential calls.
This posting presents an example of a mediator component  that calls a web service,
then combines the web service response data with the original mediator request data
and calls a File adapter with the combined payload.

The composite diagram for this example looks this

Composite.xml

 The processing is completed using a single Mediator component with a single Routing Rule as follows:

Static_Rules

Create this example by following the steps in the full article.


Tuesday May 01, 2012

Create a simple Web Service from Java Code using JDeveloper

This post covers the steps to create a simple department details web service that can be used with other examples.

We will use bottom up development, meaning we will create a new web service based on existing Java code.
The following instructions will create a new application and add a project to contain the web service.

Read the full article

Wednesday Jun 08, 2011

Unit Testing with JUnit and JDeveloper 11g

This article provides a quick overview of JUnit integration in JDeveloper 11g

Main Topics

  • Verify the JUnit Extension in JDeveloper
  • Create a parallel source directory for tests   (Optional)
  • Adding a JUnit Test Case to the Java Project
  • Implementing a Test Case
  • Running the JUnit Test Cases

Extra Topics
  • JUnit 4 Test Suite Class 
  • JUnit Test Fixture Example

Read the Full Article here


Tuesday Feb 22, 2011

SOA Suite 11g Native Format Builder Complex Format Example

This rather long posting details the steps required to process a grouping of fixed length records using Format Builder.   If it’s 10 pm and you’re feeling beat you might want to leave this until tomorrow. 
But if it’s 10 pm and you need to get a Format Builder Complex template done, read on…


The goal is to process individual orders from a file using the 11g File Adapter and Format Builder


Sample Data
===========
001Square Widget            0245.98
102Triagular Widget         1120.00
403Circular Widget           0099.45
ORD8898302/01/2011
301Hexagon Widget         1150.98
ORD6735502/01/2011


The records are fixed length records representing a number of logical Order records.
Each order record consists of a number of item records starting with a 3 digit number,
followed by a single Summary Record which starts with the constant ORD.


How can this file be processed so that the first poll returns the first order?

001Square Widget            0245.98
102Triagular Widget         1120.00
403Circular Widget           0099.45
ORD8898302/01/2011

And the second poll returns the second order?

301Hexagon Widget           1150.98
ORD6735502/01/2011

Note: if you need more than one order per poll, that’s also possible,
see the “Multiple Messages” field in the “File Adapter Step 6 of 9” snapshot further down.

To follow along with this example you will need

- Studio Edition Version 11.1.1.4.0    with the  
- SOA Extension for JDeveloper 11.1.1.4.0 installed

Both can be downloaded from here:  http://www.oracle.com/technetwork/middleware/soasuite/downloads/index.html

You will not need a running WebLogic Server domain to complete the steps and Format Builder tests in this article.

To see the full steps refer to the Full Post


Thursday Jul 01, 2010

Testing Oracle 11g Business Rules directly from Java


In my earlier post Testing Business Rules with JDeveloper Rule Designer I presented an example of testing rules using the JDeveloper Rules Designer.

While that’s nice, testing rules from a simple Java Class is even better.

This article presents an example of how the 11g rule engine can be called locally from a standalone Java application.

With this technique, the rules and decision functions authored using JDeveloper are loaded from the file system and called directly from Java.

Tests can be run from a command line or from within JDeveloper,  No Application Server is required. 

Let me repeat that part,  because I really like it,
Rule Tests can be run without a running WebLogic Server

This provides a simple and efficient way to write rules, rapidly test them and analyze the results without the need to deploy the composite. 

The approach uses two Java Classes,

The RuleTester.java Class is a generic testing harness that will call the Rules Engine, pass input data and return results.
The RuleTester.java class does not need to be modified by the developer.

The second Java Class must be implemented by the developer.
This class creates the required test data and invokes RuleTester.
An example of both classes are provided below.

The following example illustrates the following points;

  • Loading a rule dictionary from the file system.
  • Creating the necessary Java and XML test facts.
  • Calling the decision service and running the rules
  • Output of the decision service results

RuleTester.java

package rulesproject;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import oracle.rules.sdk2.decisionpoint.*;
import oracle.rules.sdk2.dictionary.RuleDictionary;
import oracle.rules.sdk2.exception.SDKWarning;
import oracle.rules.rl.RuleSession;
import oracle.rules.rl.extensions.trace.RuleEngineState;
import oracle.rules.rl.extensions.trace.TraceAnalysis;
import oracle.rules.rl.trace.DecisionTrace;
import oracle.rules.rl.trace.FactTrace;
import oracle.rules.rl.trace.RuleTrace;
import oracle.rules.rl.trace.TraceEntry;

/**
 * A Java Class that demonstrates how to load an Oracle 11g Rules Dictionary
 * from a file system location and execute a decision Function.
 * The class is intended to be used only as Rule development / prototyping tool.
 * The rules and decision service to be tested are expected to located in a .rules
 * file on the file system created using the JDeveloper 11g Rules Editor.
 * The rules should be contained in a JDeveloper SOA Rules Composite Application,
 * for example a "Composite Business Rule" application.
 * Rules are tested in a slave JVM automatically started by JDeveloper.
 * A running WebLogic Application Server is not required.
 */
public class RuleTester {
 public RuleTester() {
 super();
 }
 
 /* Initialize loads the Rule dictionary from the specified file system location and creates a Rule Decision Point.
 * @param dictionaryLocation The full path to the .rules file.
 * @param decisionFunctionName The name of the Decision Function that will be called.
 * The function is defined using the JDevleloper rule editor 
 */
 private static DecisionPointInstance initialize(String dictionaryLocation, String decisionFunctionName) throws Exception {
 
 DecisionPointInstance pointInstance = null;
 if(dictionaryLocation == null || decisionFunctionName == null)
 throw new Exception("RuleProcessor must have all input properties to successfully initialize.");
 
 // Load Decision Point using Dictionary on File System
 DecisionPoint decisionPoint = new DecisionPointBuilder()
 .with(decisionFunctionName)
 .with(loadRuleDictionary(dictionaryLocation)) 
 .build();
 pointInstance = decisionPoint.getInstance(); 
 RuleSession session = pointInstance.ruleSession();
 session.callFunctionWithArgument("setDecisionTraceLevel", RuleSession.DECISION_TRACE_DEVELOPMENT);
 
 System.out.println("RuleTester Initialized");
 return pointInstance;
 }
 
 
 
 /**
 * Loads the rule dictionary from the specified dictionaryPath
 * @param dictionaryLocation The full path to the .rules file.
 * @return A rule dictionary object
 * 
 */
 private static RuleDictionary loadRuleDictionary(String dictionaryLocation) throws Exception{
 RuleDictionary dict = null;
 Reader reader = null;
 Writer writer = null;
 
 try {
 reader = new FileReader(new File(dictionaryLocation));
 dict = RuleDictionary.readDictionary(reader, new DecisionPointDictionaryFinder(null));
 List<SDKWarning> warnings = new ArrayList<SDKWarning>();
 
 dict.update(warnings);
 if (warnings.size() > 0 ) { 
 System.err.println("Validation warnings: " + warnings);
 }
 
 } finally {
 if (reader != null) { try { reader.close(); } 
 catch (IOException ioe) {ioe.printStackTrace();}}
 if (writer != null) { try { writer.close(); } 
 catch (IOException ioe) {ioe.printStackTrace();}}
 }
 
 return dict;
 }
 
 /**
 * Produces a trace of the Rules Session to the Standard Output device
 * @param pointInstance The decision point instance for the test session.
 
 */
 private static void outputTrace(DecisionPointInstance pointInstance) throws Exception
 {
 DecisionTrace trace = pointInstance.decisionTrace();
 TraceAnalysis tAnalysis = new TraceAnalysis(trace);
 
 List<TraceEntry> traceList = trace.getTraceEntries();
 System.out.println("Trace list size is " + traceList.size() );
 
 if(traceList.size() > 0) {
 // Iterator<TraceEntry> it = traceList.iterator();
 for(int t=0; t<traceList.size(); t++)
 {
 TraceEntry entry = traceList.get(t);
 
 RuleEngineState engineState = tAnalysis.getRuleEngineState(entry);
 
 // Fact Trace List for Trace Entry
 List<FactTrace> factTraceList = engineState.getFacts();
 System.out.println("Trace entry " + (t+1) + " Engine has " + factTraceList.size() + " Facts");
 for(int i=0; i< factTraceList.size(); i++)
 { 
 FactTrace fTrace = (FactTrace) factTraceList.get(i);
 System.out.println("Fact " + (i+1) + ": " + fTrace.getFactType());
 }
 
 // Output Fired Rules for Trace Entry
 List<RuleTrace> firedRulesList = engineState.getFiredRules();
 for(int i=0; i< firedRulesList.size(); i++)
 { 
 RuleTrace frTrace = (RuleTrace) firedRulesList.get(i);
 System.out.println("Fired rule " + frTrace.getRuleName());
 }
 }
 }
 }
 
 /**
 * Execute the Rule Decision Function and return the results.
 * @param dictionaryLocation The fully qualified path of the .rules file containing the rules.
 * Created by JDeveloper rule editor.
 * @param decisionFunctionName The name of the Decision Function in the Rules Dictionary that will be called.
 * @param inputs An ArrayList containing the parameters required by the decision service in order or appearance.
 * @param trace A boolean flag indicating whether a trace for the session should be output to the standard out device.
 * @return A modified list of objects returned by the specified rule decision service
 */
 public static List runRules(String dicrtionaryLocation, String decisionFunctionName, ArrayList inputs, boolean trace) throws Exception { 
 
 List<Object> ruleResult = null; 

 DecisionPointInstance pInstance = initialize(dicrtionaryLocation, decisionFunctionName);
 
 if(pInstance == null)
 throw new Exception("RuleTester not intialized.");
 
 System.out.println("Running Rules");
 
 if (inputs != null)
 { 
 pInstance.setInputs(inputs);
 
 // invoke the decision point with our inputs
 ruleResult = pInstance.invoke();
 
 if (ruleResult == null || ruleResult.isEmpty()){
 System.out.println("RuleTester: No results returned by rules"); 
 }
 else System.out.println("RuleTester: " + ruleResult.size() + " result(s) returned.");
 
 if(trace)
 outputTrace(pInstance);
 }
 return ruleResult;
 }
 
}

Download RuleTester.java

MyShippingCostTester.java

package rulesproject;

import example.rules.OrderT;
import example.rules.ObjectFactory;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class MyShippingCostTester {
 public MyShippingCostTester() {
 super();
 }
 
 /**
 * Creates a list of Shipping Codes Java Facts for input to the rule engine. 
 * @return A populated List of ShipCode objects
 */
 public static List<ShipCode> createShipCodesTestData()
 { 
 ShipCode row1 = new ShipCode();
 row1.setProductId("001");
 row1.setShipCode("C");
 
 ShipCode row2 = new ShipCode();
 row2.setProductId("002");
 row2.setShipCode("A");
 
 List<ShipCode> codes = new ArrayList<ShipCode>();
 codes.add(row1);
 codes.add(row2);
 
 return codes;
 }
 
 /**
 * Creates a sample order for input to the rule engine. Order is an XML type Fact.
 * @return A populated sample OrderT object
 * @throws JAXBException If unmarshalling is unsuccessful
 */
 public static OrderT createOrderTestData() throws JAXBException {
 
 String sampleOrder =
 "<Order xmlns=\"http://www.rules.example\">\n" + 
 " <orderId></orderId>\n" + 
 " <items>\n" + 
 " <item>\n" + 
 " <productId>001</productId>\n" + 
 " <quantity>3</quantity>\n" + 
 " <unitPrice>5.99</unitPrice>\n" + 
 " <extraCharge>false</extraCharge>\n" + 
 " </item>\n" + 
 " <item>\n" + 
 " <productId>123</productId>\n" + 
 " <quantity>1</quantity>\n" + 
 " <unitPrice>34.99</unitPrice>\n" + 
 " <extraCharge>false</extraCharge>\n" + 
 " </item>\n" + 
 " </items>\n" + 
 "</Order>";
 
 OrderT order = null;
 
 // XML Facts are represented by JAXB types. 
 // Use the Generated types to parse an xml test message
 JAXBContext jaxbContext2 = JAXBContext.newInstance("example.rules");
 Unmarshaller unMarsh = jaxbContext2.createUnmarshaller();
 ByteArrayInputStream is = new ByteArrayInputStream(sampleOrder.getBytes());
 Object obj = unMarsh.unmarshal(is);
 JAXBElement jobj = (JAXBElement) obj;
 order = (OrderT) jobj.getValue();
 
 // Write input Order to stdout for later comparison to Order returned by rule engine 
 System.out.println("Input Order Is:");
 Marshaller marshaller2 = jaxbContext2.createMarshaller();
 marshaller2.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 marshaller2.marshal( obj, System.out );
 
 return order; 
 } 
 
 public static void main(String args[]) throws Exception {

 final String dictionaryLocation = "C:\\projects\\BobsRulesApp\\oracle\\rules\\rulesproject\\OracleRules1.rules";
 final String decisionServiceName = "DetermineShippingCosts";
 
 // Create an array of inputs that match the Rules Decision Function parameters
 ArrayList inputs = new ArrayList();
 inputs.add(createOrderTestData()); // OrderT
 inputs.add(createShipCodesTestData()); // Ship Code List
 
 // Execute the Rules passing in the Test Order and Shipping Codes
 List resultList = RuleTester.runRules(dictionaryLocation, decisionServiceName, inputs, true); // trace on
 
 // Output the results
 if(resultList != null)
 {
 // Only a single Order object returned from rules decision function
 OrderT result = (OrderT) resultList.get(0); 
 
 // Output Modified Order returned from Rules Engine to stdout 
 JAXBContext jaxbContext = JAXBContext.newInstance(OrderT.class);
 Marshaller marshaller = jaxbContext.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 ObjectFactory objF = new ObjectFactory();
 marshaller.marshal( objF.createOrder(result), System.out );
 }
 }
 
 

}


Download MyShippingCostTester.java


Running a test
The rules are tested within JDeveloper by right clicking on the MyShippingCostTester.java file and choosing Run.

JDeveloper launches a JVM using the application class path which includes the required rule engine jars.

When run within JDeveloper, the test output is displayed in the Log window as shown below.

In the modified order that is returned, rules have updated the extraCharge element of the first item to indicate additional shipping charges will apply for this item.


A Note about Java and XML Rule Types

If the rules to be tested are based on Java facts then the Java Classes that were provided to the rule engine during fact creation will be on the classpath at runtime.
If the rules to be tested are based on XML, then JDeveloper has generated JAXB content model classes for the input types sent to the rules engine.
The java types for XML facts are generated by JDeveloper during rule creation in the rule editor.
The JAXB types and stored in the  .rulesdesigner folder under the project, which is not visible from within jdeveloper.
These are the types that must be used to create input test data for xml facts.

If XML Facts are being tested from within JDeveloper,
The .rulesdesign/Jaxb_classes folder must be added to project classpath so a run of MyShippingCostTester.java and RuleTester.java can find the types at run time.

Download the complete JDeveloper Project

This provided zip contains a JDeveloper 11.1.1.5 project.

Localizing the Project

The MyShippingCostTester.java file contains a fully qualified path to the .rules file.
The path must be updated in the source to point to the location of the .rules file on the local file system.
To run a test, right click on the MyShippingCostTester.java file and choose Run
The JDeveloper Log window should display the results shown above in the screen snapshot.

The complete example can be downloaded in a zip file from GitHub here

About

Picture of Bob

I am an Oracle Architect specializing in Service Oriented Architecture and Business Process Management.


Any code presented is for educational purposes only, no warranty or support is implied.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today