Skip navigation.

Fusion Middleware

ADO .NET c# Connection Pooling with vFabric SQLFire

Pas Apicella - Thu, 2013-04-11 05:29
Whether it's accessing a database using JAVA or in this case c# I always want to use a connection pool and in this example I show and simple way to do this with a c# ADO .NET client accessing SQLFire.

1. Add a reference to your Visual Studio project in the VMware.Data.SQLFire.dll. This DLL is installed in the  

vFabric_SQLFire_11_bNNNNN\adonet\lib directory.


2. Reference the driver namespace in each source file where you want to use SQLFire components. For example, include this directive with all other references required in your application:

using VMware.Data.SQLFire;

3.  Create a c# console application as follows
  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VMware.Data.SQLFire;
using System.Data;

namespace SQLFireDemo
{
    class QueryDemo
    {
        private string sqlfHost = "192.168.1.4";
        private int sqlfPort = 1527;

        public QueryDemo()
        {
        }

        private string GetConnectionString()
        {
            return string.Format(@"server={0}:{1}", sqlfHost, sqlfPort);
        }

        public void run()
        {
            using (SQLFClientConnection conn = new SQLFClientConnection(GetConnectionString()))
            {
                conn.Open();
                SQLFCommand command = new SQLFCommand
                      (string.Format("SELECT * FROM dept"), conn);
                SQLFDataReader reader = command.ExecuteReader();

                try
                {
                    StringBuilder row = new StringBuilder();
                    while (reader.Read())
                    {
                        Console.WriteLine(string.Format("Dept[deptno={0}, dname={1}]",
                                          reader.GetString(0),
                                          reader.GetString(1)));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                finally
                {
                    reader.Close();
                }
            }

        }

        static void Main(string[] args)
        {
            QueryDemo test = new QueryDemo();
            test.run();
        }
    }
}

Output as follows

Dept[deptno=10, dname=ACCOUNTING]
Dept[deptno=20, dname=RESEARCH]
Dept[deptno=30, dname=SALES]
Dept[deptno=40, dname=OPERATIONS]
Dept[deptno=50, dname=MARKETING]
Dept[deptno=60, dname=DEV]
Dept[deptno=70, dname=SUPPORT]
Press any key to continue . . .http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware

vFabric GemFire and the Native Client World using c#

Pas Apicella - Mon, 2013-04-08 05:17
Recently I had to step out of my comfort zone and learn how to create a c# client to access a GemFire 7 distributed system for a demo to a customer. OIf course there was more to it then just that but this outlines what you need to do to connect as a c# client to GemFire. I was using the following here.
  • Visual Studio 2012
  • GemFire 32 bit Naive Client
1. Install GemFire Native client 32 bit or 64 bit depending on your OS. It can be downloaded from the following location.

https://my.vmware.com/web/vmware/info/slug/application_platform/vmware_vfabric_gemfire/7_0

2. Once installed setup an ENV variable as shown below pointing to the location of the native client install.

C:\Windows\system32>echo %GFCPP%
C:\vFabric_NativeClient_32bit_7010

3. In your Visual Studio 2012 Project / Solution add a reference to GemFire DLL as shown below.




4. In Visual Studio 2012 create a cache.xml as shown below. This client cache is going to use a locator to connect to a cache server instance for the client itself.

xml/cache.xml
  
<?xml version="1.0"?>
<!DOCTYPE client-cache PUBLIC
    "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
    "http://www.gemstone.com/dtd/cache7_0.dtd">

<client-cache>
  <pool name="client" subscription-enabled="true">
    <locator host="172.16.62.1" port="10334" />
  </pool>

  <region name="CommandRegion">
    <region-attributes refid="PROXY" pool-name="client">
    </region-attributes>
  </region>
  
  <region name="changeTrackingRegion">
    <region-attributes data-policy="normal" pool-name="client">
    </region-attributes>
  </region>
</client-cache>

5. Create 2 c# classes as shown below.

GemFireClient.cs
  
using GemStone.GemFire.Cache.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace pivotal.au.company.poc
{
    class GemFireClient
    {
        private static bool isStarted = false;
        private static GemFireClient instance = new GemFireClient();
        private string configFileLocation = "xml/cache.xml";
        private Properties<string, string> properties = Properties<string, string>.Create<string, string>();
        private CacheFactory cacheFactory;
        private Cache cache;
        IRegion<string, string> ctrRegion;

        private GemFireClient()
        {
            Console.WriteLine("Reading properties file xml/cache.xml...");
            string clientCacheXml = getCacheConfigLocation(configFileLocation);
            properties.Insert("cache-xml-file", clientCacheXml);
            Serializable.RegisterPdxSerializer(new ReflectionBasedAutoSerializer());

            cacheFactory = CacheFactory.CreateCacheFactory(properties);
            cache = cacheFactory.Create();
  
            ctrRegion = cache.GetRegion<string, string>("changeTrackingRegion");
            ctrRegion.GetSubscriptionService().RegisterRegex("."); 
            
            Console.WriteLine("ctrRegion size = " + ctrRegion.Count);
        }

        public static GemFireClient getInstance()
        {
            return instance;
        }

        public void closeClientCache()
        {
            cache.Close();
            Console.WriteLine("Client Cache closed...");
        }

        public Cache getCache()
        {
            return cache;
        }

        private static string getCacheConfigLocation(string cacheXml)
        {
            var directoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            if (File.Exists(System.Environment.GetEnvironmentVariable("COMPANY_CONFIG") + "/" + cacheXml) == true)
            {
                return System.Environment.GetEnvironmentVariable("COMPANY_CONFIG") + "/" + cacheXml;
            }
            else if (File.Exists(Path.Combine(directoryName, cacheXml)) == true)
            {
                return Path.Combine(directoryName, cacheXml);
            }
            else
            {
                throw new SystemException("Unable to find /" + cacheXml);
            }
        }
    }
}

GemFireTest.cs
  
using pivotal.au.company.poc.domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GemStone.GemFire.Cache.Generic;

namespace pivotal.au.company.poc
{
    class GemFireTest
    {
        GemFireClient gfClient;

        public void doInsert()
        {
            gfClient = GemFireClient.getInstance();

            // get command region
            IRegion<string, Command> commandRegion = gfClient.getCache().GetRegion<string, Command>("CommandRegion");

            // insert a Command Object into the region
            Command command = new Command();
            command.eventType = "INSERT";
            command.tableName = "Holiday";
            command.tableKey = "1";
            command.sequence = 31;
            command.payload = new Dictionary<object, object>()
                { 
                  {"Id", "1"},
               {"name", "apples"},
                  {"createdate", "10-10-2009"}
                };

            Console.WriteLine(command.ToString());

            commandRegion[command.tableKey] = command;

        }

        public void queryCommandRegion()
        {
            gfClient = GemFireClient.getInstance();

            Console.WriteLine("about to query commandRegion");

            QueryService<string, Command> queryService = gfClient.getCache().GetQueryService<string, Command>();
            Query<Command> qry = queryService.NewQuery("SELECT * FROM /CommandRegion");
            ISelectResults<Command> results = qry.Execute();
            SelectResultsIterator<Command> iter = results.GetIterator();
            while (iter.MoveNext())
            {
                Console.WriteLine(iter.Current.ToString());
            }

        }

        public void closeCache()
        {
            gfClient.closeClientCache();
        }

        public void run()
        {
            GemFireTest test = new GemFireTest();
            test.doInsert();
            test.queryCommandRegion();
            test.closeCache();
        }

    }
}

Output omitted but this should give you the general idea.

http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware

Reach the Oracle WebCenter Summit with Fishbowl Solutions at Collaborate 13

I have been using the analogy that sometimes getting WebCenter projects started, progressed or completed is like climbing a mountain. Customers aren’t always sure where to begin, how to stay on path, or what obstacles may lie ahead. Most customers seem to want to evolve their WebCenter use cases, say from standard content management to an enterprise portal, but not knowing such things as the amount of effort required, technical complexities, and deployment options tends to keep such projects at the base of the proverbial WebCenter mountain.

What better place to start your trek up that mountain than Denver, Colorado – site of Collaborate 13. Fishbowl Solutions will be there, and we would enjoy discussing your WebCenter projects and how we might assist in helping those projects get started, progressed and completed – avoiding the cliffs and jagged rocks along the way. We would also like to share with you some new and exciting ways that your trek can be made easier through our value-add WebCenter solutions. Here is a quick description of the solutions we will highlight at Collaborate 13:

These solutions will be demonstrated in our booth – #1277 – and will be discussed across our six presentations. Be sure to check out our Collaborate 13 page for all the details on our Collaborate activities. We look forward to helping you start your WebCenter ascent at Collaborate 13.

The post Reach the Oracle WebCenter Summit with Fishbowl Solutions at Collaborate 13 appeared first on C4 Blog by Fishbowl Solutions.

Categories: Fusion Middleware, Other

Oracle WebCenter PS6 released!

Last year back in Feb we had PS5 and now with PS6 the WebCenter Suite released yesterday I can say its all just getting better and better!..

A rundown of the new Jdev 11.1.1.7.0 Enhancements can be seen here

http://www.oracle.com/technetwork/developer-tools/jdev/index-088099.html

Here are some of the items that catch my eye and you may have seen it on the twitter stream with a couple early tweets before the official release.

Firstly the new Skyros Skin (I’m presuming after the Greek Island)
Very clean and great looking skin; uses a lot of CSS3 properties instead of hundred of images to structure components – tabs degrades nicely for older browsers IE8 and below ie rounded corners become square.

Also a few new skin selector properties that tidy up the structure for better skinning development – I’ll try to post some updates later on to give you a rundown of some of the new enhancements with skinning.

You can see it in action in the new PS6ADF Faces Rich Client here

http://jdevadf.oracle.com/faces11117/

There are a few DVT extras like Sunburst; although I’m sorry to say I’ve never been too impressed with DVTs you get out of the box.

PanelGridLayout makes it across from R2 into R1PS6 looks promising
Follows the CSS3 specs for grid layout so it can be optimized for layout performance and is also the recommended UI layout component for most pages.

Runtime code editor Finally colour coded goodness!

I believe it’s using codeMirror great job.

File Uploader also looks interesting haven’t tried it out yet – drag drop support is interesting with java support for older browsers looking forward to seeing it in action.

 


The post Oracle WebCenter PS6 released! appeared first on C4 Blog by Fishbowl Solutions.

Categories: Fusion Middleware, Other

Testing Activiti BPM on WebLogic 12c

Edwin Biemond - Fri, 2013-03-29 14:33
Activiti is a great open source workflow + BPM platform, which you can use in your own java application (embedded) or test it in the provided Rest or Web demo applications. Activiti also provides  an Eclipse designer plugin which you can use to create your own BPMN 2.0 definitions and export this to the Activiti applications. In blogpost I will show you the steps how to get this working on the

Upgrading to Oracle WebCenter Content 11g: Use Upgrade Assistant or Migrate Content to a New Instance?

This post comes from Alan Mackenthun – Fishbowl’s Technical Program Manager.

We held a webinar recently to introduce our 11g Upgrade Package. One good question was asked a couple times and really merits a better answer than could be delivered in the Q&A session so I thought we could elaborate a bit more here. The question is: Is it better to use the 11g Upgrade Assistant to upgrade in place or to migrate everything to a fresh new 11g instance. The short answer is – It depends:)  Another good answer is – Neither.

You may now understand why I wanted to expand on the short answers given at the end of the webinar. I’ll describe the two approaches below as well as a potentially better 3rd way.  Whichever approach is selected, the process needs to be well thought out, clearly defined, and tested before doing anything in production.

Migrating to New Instances

Migrating to new instances isn’t really an upgrade, but it is very common. For a long time, this was the standard recommended way that we’d execute upgrades. In this scenario, wholly new  instances of Content Server are installed and all configuration, status information, and content is migrated to the new instances. This is necessary if you are planning to change the variety of hardware or database to be used going forward.

Care must be taken to get all configuration migrated. The Configuration Migration Utility (CMU) is used to migrate the bulk of the configuration, but archiver is used to migrate custom table data. Also, many add-ons or optional components require special steps to migrate other relevant information.

The migration of content is typically performed with the Archiver applet. This process is error prone and needs to be monitored carefully. Migrating content in a workflow lies somewhere between difficult to not supported. If a lot of content needs to be migrated, a custom process is likely to be recommended. If the instance manages a lot of content, a migration can take a long time and this needs to be accounted for in the planning. Fishbowl has created the Content Migrator to support the migration of content from one instance to another without needing to use Archiver.

It’s all doable, but migrations are usually more complicated than the other options.

Upgrade Assistant

Use of the Upgrade Assistant allows for ‘in place’ upgrades.  The high level process involves:

  1. Installing WebLogic Server (or the supported container of your choice)
  2. Installing the WCC installation files
  3. Then running the Upgrade Assistant pointing to the existing instance of Content Server.

The Upgrade Assistant will take over the existing instance and upgrade the file system and database schema to support 11g. It will disable any older patch components and enable the 11g versions of any standard components. It will also disable any custom components and give you the list of these. For this reason, it is very important to do this in a quality dev environment 1st as it will take time to enable, test, and likely fix any custom components in use in your system. Once the dev instance is upgraded and tested, the production instance is upgraded in exactly the same way, but after the Upgrade Assistant finishes, you can install the upgraded components from the dev instance, restart and do your final system testing before turning it back over to your users.

The benefit of leveraging the Upgrade Assistant is that you don’t have to migrate the configuration and content to the new instance. If you aren’t changing your search index (Verity is no longer supported in any way), you don’t have to immediately rebuild your search index either though it is highly recommended that a rebuild be completed after the upgrade.

The downside of this approach is that you are directly working in the production instance. There is no way around significant downtime and if something goes wrong you’re under the gun to rectify it immediately or you have to restore everything from tape and try again later.

Copy & Upgrade in Place

The 3rd options is to make a copy of the production instance and upgrade it in place.  As long as you’re not changing the variety of operating system or the type of database, this has worked well for us. If there’s a lot of content, the copying itself can take a fair amount of time, but then the upgrade can be executed on new and refreshed hardware and the production system need only be down while the copy is being made. After the copy, the old Content Server can be restarted in read only mode until you can switch over to the new system.  Sometimes this is only done to make a new dev or stage instance if the old instances were out of sync. After having run the upgrade in those two environments, customers may be comfortable running the production upgrade in place.

If you’d like us to assist you with an upgrade to WCC 11g we’ll ask that you complete an upgrade questionnaire. We put this together to most efficiently estimate the level of effort for an upgrade. Some of the questions included on the questionnaire help us determine which of these approaches might best fit your needs.

If you’d like to see what we think, please email any of us here or sales@fishbowlsolutions.com and request a copy of the upgrade questionnaire.

The post Upgrading to Oracle WebCenter Content 11g: Use Upgrade Assistant or Migrate Content to a New Instance? appeared first on C4 Blog by Fishbowl Solutions.

Categories: Fusion Middleware, Other

Why NoSQL became MORE SQL and why Hadoop will become the Big Data Virtual Machine

Steve Jones - Fri, 2013-03-22 03:27
A few years ago I wrote an article about "When Big Data is a Big Con" which talked about some of the hype issues around Big Data.  One of the key points I raised was about how many folks were just slapping on Big Data badges to the same old same old, another was that Map Reduce really doesn't work they way traditional IT estates behave which was a significant barrier to entry for Hadoop as a new
Categories: Fusion Middleware

Fishbowl Webinar – A Path, Package, and Promise for WebCenter Content 11g Upgrades

Oracle Universal Content Management 10gR3 was released in May 2007. Since that time, Oracle WebCenter Content 11g has been released, and Oracle WebCenter 12c is on the horizon. For 10gR3 customers, the next step down the WebCenter path is to upgrade to 11g. However, some customers don’t know where to begin in terms of an upgrade – not when their current version is supporting numerous business processes, contains thousand of high-value content items, and has been customized numerous time to meet business requirements.

Join Jason Lamon, Senior Marketing Associate, and Alan Mackenthun, Technical Program Manager at Fishbowl Solutions as they discuss Fishbowl’s path, package and promise for WebCenter Content 11g upgrades. They are also privileged to be joined by Mike Kohorst – IT Application Manager at Ryan Companies, who will discuss their recent 11g upgrade success, as well as their future plans for the system. We hope you will be able to join us!

Date: Thursday, March 21st
Time: 1 pm EST, Noon CST
Register: https://www2.gotomeeting.com/register/684506914

 

The post Fishbowl Webinar – A Path, Package, and Promise for WebCenter Content 11g Upgrades appeared first on C4 Blog by Fishbowl Solutions.

Categories: Fusion Middleware, Other

BTVision iPlayer not working - and the excuses BT use

Steve Jones - Tue, 2013-03-12 10:26
I've had an experience in the last few months with the folks from BT that really brought home how bad support can be when they have a real issue and how they look to trot out excuses to fob you off when they dont actually have a fix. So in January iPlayer stopped working at my mother's house.  She isn't a techy so I took over support.  The first call went fine, and a secondary follow up call
Categories: Fusion Middleware

“Fishbowl Mobile Library” Android Tablet App Now Available on Google Play

Free Application Showcases WebCenter Mobile Access Capabilities for Sales Enablement and Offline Content Access

Fishbowl Solutions is excited to announce the release of our Fishbowl Mobile Library Android application on the Google Play Store. This free version of Fishbowl’s Mobile Tablet Application for Oracle WebCenter Content allows customers to experience mobile WebCenter functionality first hand. By enabling mobile access to Oracle WebCenter Content, users can find, store, view, and organize content from the Oracle WebCenter repository directly on their tablets.

Features of the Fishbowl Mobile Library app include access to Oracle WebCenter Content with the ability to view content including PDFs, HTML, images, and video, as well as the option to keep local copies of content items for offline use. These copies are synced with WebCenter when reconnected. Customized Folder View options enable the user to organize local content into a personalized folder structure and the Content Sharing feature provides the option to add items to an email cart which emails links to download items from a secure temporary download site.

The Android application is built on Fishbowl’s Mobility API and serves as a reference for mobile applications integrated with Oracle WebCenter Content. This mobile content library application framework is currently in production on both Android Tablets and the Apple iPad.

To learn more about the Fishbowl Mobile Library app, please visit our Fishbowl Solutions Mobile Tablet App Page or download the app from the Google Play Store.

The app is also available for iPad from the iTunes Store download the free Fishbowl ECM Mobile App Download on iTunes.

The post “Fishbowl Mobile Library” Android Tablet App Now Available on Google Play appeared first on C4 Blog by Fishbowl Solutions.

Categories: Fusion Middleware, Other

Implementing an AsyncEventListener for Write-Behind Cache Event Handling

Pas Apicella - Mon, 2013-03-04 03:45
As part of GemFire 70 release they have introduced as AsyncEventListener for write behind capability which is more or less very similar to the Gateway Listener in GemFire 6.x

An AsyncEventListener receives callbacks for events that change region data. You can use an AsyncEventListener implementation as a write-behind cache event handler to synchronize region updates with a database.

It documented as follows.

http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/events/implementing_write_behind_event_handler.html

So how would my cache.xml file for a member look like here.
  
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
    "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
    "http://www.gemstone.com/dtd/cache7_0.dtd">

<cache>
    <async-event-queue id="GreenplumQueue" parallel="true" batch-size="500">
       <async-event-listener>
             <class-name>vmware.pivotal.example.listener.GreenplumGatewayListener</class-name>
       </async-event-listener>      
    </async-event-queue>
    <cache-server port="40001" notify-by-subscription="true"/>
    <region name="greenplumRegion">
      <region-attributes refid="PARTITION_REDUNDANT" async-event-queue-ids="GreenplumQueue"/>
   </region>
</cache>

Finally the code to write an AsyncEventListener would be as follows.
  
package vmware.pivotal.example.listener;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import vmware.pivotal.example.dao.jdbcbatch.JdbcBatch;
import vmware.pivotal.example.dao.jdbcbatch.JdbcBatchDAO;

import com.gemstone.gemfire.cache.Declarable;
import com.gemstone.gemfire.cache.Operation;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;

public class GreenplumGatewayListener implements AsyncEventListener, Declarable
{

 private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
 private ApplicationContext context;
 private static final String BEAN_NAME = "jdbcBatchDAOImpl";
 private JdbcBatchDAO jdbcBatchDAO;
 
 public GreenplumGatewayListener()
 {
     context = new ClassPathXmlApplicationContext("application-context.xml");
     jdbcBatchDAO = (JdbcBatchDAO) context.getBean(BEAN_NAME);  
     logger.log (Level.INFO, "GreenplumGatewayListener started...");
 }
 
 @Override
 public boolean processEvents(@SuppressWarnings("rawtypes") List<AsyncEvent> list) 
 {
     logger.log (Level.INFO, String.format("Size of List<GatewayEvent> = %s", list.size()));
     List<JdbcBatch> newEntries = new ArrayList<JdbcBatch>();
     
     List<JdbcBatch> updatedEntries = new ArrayList<JdbcBatch>();
     List<String> destroyedEntries = new ArrayList<String>();
     int possibleDulicates = 0;
     
     for (@SuppressWarnings("rawtypes") AsyncEvent ge: list)
     {
       
       if (ge.getPossibleDuplicate())
        possibleDulicates++;
        
       if ( ge.getOperation().equals(Operation.UPDATE)) 
       {
      updatedEntries.add((JdbcBatch) ge.getDeserializedValue());
       }
       else if ( ge.getOperation().equals(Operation.CREATE))
       {
         newEntries.add((JdbcBatch) ge.getDeserializedValue());
       }
       else if ( ge.getOperation().equals(Operation.DESTROY))
       {
      destroyedEntries.add(ge.getKey().toString());
       }
      
     }
     
     if (newEntries.size() > 0)
     {
      jdbcBatchDAO.storeInsertBatch(newEntries); 
     }
     
     if (updatedEntries.size() > 0)
     {
      jdbcBatchDAO.storeUpdateBatch(updatedEntries);
     }
     
     if (destroyedEntries.size() > 0)
     {
      jdbcBatchDAO.storeDeleteBatch(destroyedEntries);
     }
     
     logger.log (Level.INFO, 
           String.format("New Entries = [%s], Updated Entries = [%s], Destroyed Entries = [%s], Possible Duplicates = [%s]", 
                   newEntries.size(), 
                   updatedEntries.size(), 
                   destroyedEntries.size(), 
                   possibleDulicates));
     
     return true;
 }


 public void init(Properties arg0) {
  // TODO Auto-generated method stub
  
 }

 public void close() {
  // TODO Auto-generated method stub
  
 }

}
http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware

Java needs to start again... from BEFORE JavaSE 6

Steve Jones - Wed, 2013-02-20 09:00
Back in 2006 I wrote a post on why JavaSE 6 wasn't for the Enterprise with all of the cruft that had been added and one comment I made around the inclusion of a Web Server was its potential impact on security.  Well it appears that thanks to this bloatware approach and lack of focus on core stability Java is now one of the number 1 security threats out there.  Apple have been hacked thanks to
Categories: Fusion Middleware

MyBatis-Spring with vFabric SQLFire

Pas Apicella - Wed, 2013-02-20 04:20
MyBatis-Spring helps you integrate your MyBatis code seamlessly with Spring. Using the classes in this library, Spring will load the necessary MyBatis factory and session classes for you. This library also provides an easy way to inject MyBatis data mappers into your service beans. Finally, MyBatis-Spring will handle transactions and translate MyBatis exceptions into Spring DataAccessExceptions.

Here is a simple exampled based on the classic DEPT table.

1. We are working with a DEPT table in SQLFire defined as follows.

DEPT table
  
sqlf> describe dept;
COLUMN_NAME         |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
------------------------------------------------------------------------------
DEPTNO              |INTEGER  |0   |10  |10    |NULL      |NULL      |NO      
DNAME               |VARCHAR  |NULL|NULL|14    |NULL      |28        |YES     
LOC                 |VARCHAR  |NULL|NULL|13    |NULL      |26        |YES     

3 rows selected

2. Setup your pom.xml to include the following.

pom.xml
  
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>sqlfire-mybatis</groupId>
  <artifactId>sqlfire-mybatis</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>sqlfire-mybatis</name>
  <properties>
    <spring.version>3.1.2.RELEASE</spring.version>
    <mybatis.version>3.1.1</mybatis.version>
    <mybatis.spring.version>1.1.1</mybatis.spring.version>
    <dbcp.version>1.4</dbcp.version>
    <cglib.version>2.2.2</cglib.version>
  </properties>
  <dependencies>
 <dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>${mybatis.version}</version>
 </dependency>
 <dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>${mybatis.spring.version}</version>
 </dependency>
 <dependency>
   <groupId>commons-dbcp</groupId>
   <artifactId>commons-dbcp</artifactId>
   <version>${dbcp.version}</version>
 </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
 <dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib</artifactId>
   <version>${cglib.version}</version>
 </dependency>
  </dependencies>
  <repositories>
 <repository>
     <id>mybatis-snapshot</id>
     <name>MyBatis Snapshot Repository</name>
     <url>https://oss.sonatype.org/content/repositories/snapshots</url>
 </repository>
  </repositories>
</project>

3. Create the domain modelclass Dept.java, with the standard getter/setters for each attribute. Omitting the full class here.

Dept.java
  
package pas.au.vmware.se.mybatis.domain;

public class Dept 
{
 private int deptno;
 private String dname;
 private String loc;
 
 public Dept()
 {
  
 }
 
 public Dept(int deptno, String dname, String loc) 
 {
  super();
  this.deptno = deptno;
  this.dname = dname;
  this.loc = loc;
 }

......
 

4.Create a DeptMapper.xml file. I prefer to keep SQL out of the java class wheever I can , hence avoided using annotations here.

DeptMapper.xml
  
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="pas.au.vmware.se.mybatis.mapper.DeptMapper">
 
    <resultMap id="result" type="pas.au.vmware.se.mybatis.domain.Dept">
        <result property="deptno" column="DEPTNO"/>
        <result property="dname" column="DNAME"/>
        <result property="loc" column="LOC"/>
    </resultMap>
 
    <select id="getAll" resultMap="result">
        SELECT * FROM DEPT
    </select>

 <select id="getById" parameterType="int" resultMap="result">
  SELECT * FROM DEPT WHERE DEPTNO = #{deptno}
 </select>
    
    <insert id="insertDept" parameterType="pas.au.vmware.se.mybatis.domain.Dept">
        INSERT INTO dept (deptno, dname, loc)
        VALUES (#{deptno}, #{dname}, #{loc})
    </insert>
</mapper>

5. Create a DeptMapper interface file. Notice how this is a clean interface and no annotations to specify the SQL we are using as that's in the DeptMapper.xml file above.

DeptMapper.java
  
package pas.au.vmware.se.mybatis.mapper;

import java.util.List;

import pas.au.vmware.se.mybatis.domain.Dept;

public interface DeptMapper 
{
  public List<Dept> getAll();
  public Dept getById (int deptno);
  public void insertDept (Dept dept);
}

6. Create a service class for the DEPT table as shown below.

DeptService.java
  
package pas.au.vmware.se.mybatis.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pas.au.vmware.se.mybatis.domain.Dept;
import pas.au.vmware.se.mybatis.mapper.DeptMapper;

@Service("deptService")
public class DeptService 
{

 @Autowired
 private DeptMapper deptMapper;

 public DeptMapper getDeptMapper() {
  return deptMapper;
 }

 public void setDeptMapper(DeptMapper deptMapper) {
  this.deptMapper = deptMapper;
 }
 
 public List<Dept> getAll()
 {
  return getDeptMapper().getAll();
 }
 
 public Dept getById(int deptno)
 {
  return getDeptMapper().getById(deptno);
 }
 
 @Transactional
 public void insertDept (Dept dept)
 {
  getDeptMapper().insertDept(dept);
 }
}  

7. Create a spring application context file as shown below.

application-context.xml
  
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
     <property name="driverClassName" value="com.vmware.sqlfire.jdbc.ClientDriver" />
     <property name="url" value="jdbc:sqlfire://localhost:1527/" />
     <property name="username" value="app" />
     <property name="password" value="app" />
 </bean>

 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
 </bean>

   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
   </bean>
  
    <tx:annotation-driven />

 <context:component-scan base-package="pas.au.vmware.se.mybatis.service" />

   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
     <property name="basePackage" value="pas.au.vmware.se.mybatis.mapper" />
   </bean>
      
</beans> 

8. Finally create a test class to verify the setup as shown below.

SpringDeptTest.java
  
package pas.au.vmware.se.mybatis.test;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import pas.au.vmware.se.mybatis.domain.Dept;
import pas.au.vmware.se.mybatis.service.DeptService;

public class SpringDeptTest 
{

 /**
  * @param args
  */
 public static void main(String[] args) 
 {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "application-context.xml");
        
        DeptService deptService = (DeptService) context.getBean("deptService");
        
        Dept dept = new Dept(99, "MYBATIS-TEST", "BUNDOORA");
        deptService.insertDept(dept);
        System.out.println("New DEPT added to SQLFire\n");
          
        List<Dept> deps = deptService.getAll();
        
        for (Dept d: deps)
        {
         System.out.println(d);
        }
        
        System.out.println("\n" + deptService.getById(20));
        
 }

}

9. Run SpringDeptTest.java and verfy output as shown below.

Feb 20, 2013 9:14:39 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1fff7a1e: startup date [Wed Feb 20 21:14:39 EST 2013]; root of context hierarchy
Feb 20, 2013 9:14:39 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [application-context.xml]
Feb 20, 2013 9:14:40 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@57ac3379: defining beans [dataSource,sqlSessionFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,deptService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,deptMapper]; root of factory hierarchy
New DEPT added to SQLFire

Dept [deptno=10, dname=ACCOUNTING, loc=NEW YORK]
Dept [deptno=20, dname=RESEARCH, loc=DALLAS]
Dept [deptno=30, dname=SALES, loc=CHICAGO]
Dept [deptno=40, dname=OPERATIONS, loc=BRISBANE]
Dept [deptno=50, dname=MARKETING, loc=ADELAIDE]
Dept [deptno=60, dname=DEV, loc=PERTH]
Dept [deptno=70, dname=SUPPORT, loc=SYDNEY]
Dept [deptno=99, dname=MYBATIS-TEST, loc=BUNDOORA]

Dept [deptno=20, dname=RESEARCH, loc=DALLAS]

The full project structure is as follows showing where the XML files exists in this setup.


http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware

Big Data and smart maths aren't new, that is the GOOD THING about it

Steve Jones - Tue, 2013-02-19 12:33
One of the things that annoys me sometimes, and its quite a long list, is when people proclaim something as 'new' when in fact its just a case that its gone mainstream.  The problem I have with this is that it normally means that they've forgotten all of the learnings of previous generations of implementation and are starting from scratch and making the same old mistakes.  We saw this with the
Categories: Fusion Middleware

Train Delays - why context counts in Big Data

Steve Jones - Sun, 2013-02-17 09:50
Right now in the UK there are hundreds if not thousands of trains around the UK, all moving at different speeds and going on various routes across millions of rails, switches, points and other things.  This gives billions of pieces of information. But right here, right now I just want to know why my train is stuck and when I'll get home. The key to remember in Big Data is that its not the
Categories: Fusion Middleware

Adding JSON Documents into GemFire Cache

Pas Apicella - Tue, 2013-02-12 20:46
The JSONFormatter API allows you to put JSON formatted documents into regions and retrieve them later by storing the documents internally as PdxInstances. vFabric GemFire now supports the use of JSON formatted documents natively. When you add a JSON document to a GemFire cache, you call the JSONFormatter APIs to transform them into the PDX format (as a PdxInstance), which enables GemFire to understand the JSON document at a field level.
 
In terms of querying and indexing, because the documents are stored internally as PDX, applications can index on any field contained inside the JSON document including any nested field (within JSON objects or JSON arrays.) Any queries run on these stored documents will return PdxInstances as results. To update a JSON document stored in GemFire, you can execute a function on the PdxInstance.

You can then use the JSONFormatter to convert the PdxInstance results back into the JSON document.

Here is a simple example.

1. server side cache.xml file, in this demo we just start up one cache server

cache.xml
  
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
    "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
    "http://www.gemstone.com/dtd/cache7_0.dtd">

<cache>
    <cache-server port="40404"/>
    <region name="jsonregion">
       <region-attributes refid="REPLICATE" />
    </region>
</cache>

2. Client side cache.xml

client.xml
  
<?xml version="1.0"?>
<!DOCTYPE client-cache PUBLIC
    "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
    "http://www.gemstone.com/dtd/cache7_0.dtd">

<!--
  | Client.xml
  |
  | Configures a region as a client region in a client/server cache. The 
  | region's pool connects to a cacheserver listening on port 40404.
 -->
<client-cache>
  <pool name="client" subscription-enabled="true">
    <server host="localhost" port="40404" />
  </pool>

  <region name="jsonregion">
    <region-attributes refid="PROXY">      
    </region-attributes>
  </region>
</client-cache>  

3. Java class to insert some JSON formatted documents into the cache then how to query them back using a field from the JSON document itself.

JSONGemFireClient.java
  
package vmware.au.gemfire7.json.client;

import java.util.List;

import org.json.simple.JSONObject;

import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.query.SelectResults;
import com.gemstone.gemfire.pdx.JSONFormatter;
import com.gemstone.gemfire.pdx.PdxInstance;

public class JSONGemFireClient 
{

   public static final String REGION_NAME = "jsonregion";
   public ClientCache cache = null;
   
   public JSONGemFireClient()
   {
    cache = new ClientCacheFactory()
          .set("name", "JSONClient")
          .set("cache-xml-file", "xml/client.xml")
          .create();   
   }
 
   @SuppressWarnings("unchecked")
   public void run() throws Exception
   {
    JSONObject obj = null;
    
    System.out.println("Connecting to the distributed system and creating the cache.");
      
    // Get the exampleRegion
    Region<String, PdxInstance> jsonregion = cache.getRegion(REGION_NAME);
    System.out.println("Example region \"" + jsonregion.getFullPath() + "\" created in cache.");
    
    // add 5 entries with age = 30
     
    for (int i = 1; i <= 5; i++)
    {
      obj = new JSONObject();
      
      obj.put("name", String.format("Person%s", i));
      obj.put("age", 30);
     
      jsonregion.put(String.valueOf(i), JSONFormatter.fromJSON(obj.toJSONString()));
    }
      
    // add 5 entries with age = 20
    for (int i = 6; i <= 10; i++)
    {
      obj = new JSONObject();
      
      obj.put("name", String.format("Person%s", i));
      obj.put("age", 20);
     
      jsonregion.put(String.valueOf(i), JSONFormatter.fromJSON(obj.toJSONString()));
    }
    
    // Query region
    SelectResults<PdxInstance> sr = jsonregion.query("age = 30");
    
    System.out.println("Number of entries where age = 30 is -> " + sr.size());
    
    List<PdxInstance> entries = sr.asList();
    for (PdxInstance val: entries)
    {
     System.out.println("\n** JSON data ** ");
     System.out.println("Name = " + val.getField("name"));
     System.out.println("Full JSON data -> \n" + JSONFormatter.toJSON(val));
    }
    
    cache.close();
   }
 
   /**
    * @param args
    */
   public static void main(String[] args) 
   {
    // TODO Auto-generated method stub
    JSONGemFireClient test = new JSONGemFireClient();
    
    try 
    {
   test.run();
    } 
    catch (Exception e) 
    {
   // TODO Auto-generated catch block
   e.printStackTrace();
    }
   }

}

4. Run the java class above and verify output as follows

....
[info 2013/02/13 09:41:15.464 EST tid=0x1] Defining: PdxType[
      id=1, name=__GEMFIRE_JSON, fields=[
          age:byte:0:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=0
          name:String:1:idx0(relativeOffset)=1:idx1(vlfOffsetIndex)=-1]]
Number of entries where age = 30 is -> 5

** JSON data **
Name = Person1
Full JSON data ->
{
  "age" : 30,
  "name" : "Person1"
}

** JSON data **
Name = Person4
Full JSON data ->
{
  "age" : 30,
  "name" : "Person4"
}

** JSON data **
Name = Person2
Full JSON data ->
{
  "age" : 30,
  "name" : "Person2"
}

** JSON data **
Name = Person5
Full JSON data ->
{
  "age" : 30,
  "name" : "Person5"
}

** JSON data **
Name = Person3
Full JSON data ->
{
  "age" : 30,
  "name" : "Person3"
}
....


5. Finally use GFSH to query the region itself and you wouldn't even know your using JSON stored documents and would rely on using JSONFormatter  to convert the data back into JSON document.
  
gfsh>connect --jmx-manager=localhost[1099]
Connecting to Manager at [host=localhost, port=1099] ..
Successfully connected to: [host=localhost, port=1099]

gfsh>list regions;
List of regions
---------------
jsonregion

gfsh>query --query="select * from /jsonregion";

Result     : true
startCount : 0
endCount   : 20
Rows       : 10

age | name
--- | --------
30  | Person1
30  | Person4
20  | Person8
20  | Person10
20  | Person6
30  | Person2
30  | Person5
20  | Person9
20  | Person7
30  | Person3

NEXT_STEP_NAME : END 

More information can be found on the link below.

http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/data_serialization/jsonformatter_pdxinstances.htmlhttp://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware

IT has made its self redundant through technology

Steve Jones - Tue, 2013-02-12 06:38
There are lots of stats out there about CMOs (Chief Marketing Officers), CFOs and COOs now spending more on IT than the IT department.  Lots of this spend is on SaaS solutions and information centric solutions.  The previously powerful IT department has dropped out of contention in many cases because its not seen as adding any value. And what is the main reason for that? Well the IT department
Categories: Fusion Middleware

JSON messages with RabbitMQ

Pas Apicella - Mon, 2013-02-11 05:12
Using JSON message solution in RabbitMQ gives you something that's a bit more friendly in polyglot systems, and leaves your application with more future flexibility. Although we can use Java Objects this puts restrictions on the the recipients of your message as they're also going to need to be in Java. JSON (JavaScript Object Notation) is rather common alternative that is more flexible and portable across different languages and platforms.

In the example below we use the following

RabbitMQ 3.0 - http://www.rabbitmq.com/
JSON-Simple - http://code.google.com/p/json-simple/

1. Create a start up script to start a single RabbitMQ server.

export RABBITMQ_NODE_PORT=5676
export RABBITMQ_NODENAME=rabbit_standalone

export RABBIT_HOME=/Users/papicella/vmware/software/rabittMQ/rabbitmq_server-3.0.0

$RABBIT_HOME/sbin/rabbitmq-server -detached

netstat -an | grep 5676

2. Start as shown below.

[Mon Feb 11 21:07:17 papicella@:~/rabbitMQ/standalone-rabbit ] $ sudo ./node1.sh
Warning: PID file not written; -detached was passed.
tcp4       0      0  *.5676                 *.*                    LISTEN    
tcp46      0      0  *.5676                 *.*                    LISTEN    

3. Create a RECEIVE client which will create a QUEUE and wait for messages. IT is expecting a JSON string to be sent.

JSONRecv.java
  
package pas.au.rabbitmq30.tutorial.helloworld.json;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;

public class JSONRecv 
{
 private final static String QUEUE_NAME = "json-example";
 private ConnectionFactory factory = null;
 private JSONParser parser;
 
 public JSONRecv() 
 {
  parser = new JSONParser();
 }

 public void run () throws Exception
 {
  factory = new ConnectionFactory();
     factory.setHost("localhost");
     factory.setPort(5676);
     Connection connection = factory.newConnection();
     Channel channel = connection.createChannel();

     channel.queueDeclare(QUEUE_NAME, false, false, false, null);
     System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
     
     QueueingConsumer consumer = new QueueingConsumer(channel);
     channel.basicConsume(QUEUE_NAME, true, consumer);
     
     while (true) 
     {
       QueueingConsumer.Delivery delivery = consumer.nextDelivery();
       String message = new String(delivery.getBody()); 
       JSONObject obj = (JSONObject) parser.parse(message);
       
       System.out.println(" [x] Received '" + obj.toJSONString() + "'");
     }  
 }
 
 /**
  * @param args
  * @throws Exception 
  */
 public static void main(String[] args) throws Exception 
 {
  // TODO Auto-generated method stub
  JSONRecv test = new JSONRecv();
  test.run();
 }

}  

4. Create a SEND client and place 10 JSON objects onto the QUEUE

JSONSend.java
  
package pas.au.rabbitmq30.tutorial.helloworld.json;

import org.json.simple.JSONObject;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class JSONSend 
{
 private final static String QUEUE_NAME = "json-example";
 private ConnectionFactory factory = null;
 
 public JSONSend() 
 {
  // TODO Auto-generated constructor stub
 }
 
 @SuppressWarnings("unchecked")
 public void run() throws Exception
 {
     factory = new ConnectionFactory(); 
     factory.setHost("localhost"); 
     factory.setPort(5676);
     
     System.out.println("connected to rabbitMQ on localhost ...");
     Connection connection = factory.newConnection();
     Channel channel = connection.createChannel();

     channel.queueDeclare(QUEUE_NAME, false, false, false, null);
     for (int i = 1; i <= 10; i++)
     {
      JSONObject obj = new JSONObject();
      
      obj.put("name", String.format("Person%s", i));
      obj.put("age", new Integer(37));
     
      channel.basicPublish("", QUEUE_NAME, null, obj.toJSONString().getBytes()); 
      System.out.println(" [x] Sent '" + obj.toJSONString() + "'");
     }
     
     channel.close();
     connection.close();
 }
 
 /**
  * @param args
  * @throws Exception 
  */
 public static void main(String[] args) throws Exception 
 {
  // TODO Auto-generated method stub
  JSONSend test = new JSONSend();
  test.run();
 }

}

5. Run JSONRecv.java and verify output as follows

[*] Waiting for messages. To exit press CTRL+C

6. Run JSONSend.java and then check the output from JSONRecv.java.

 [*] Waiting for messages. To exit press CTRL+C
 [x] Received '{"name":"Person1","age":37}'
 [x] Received '{"name":"Person2","age":37}'
 [x] Received '{"name":"Person3","age":37}'
 [x] Received '{"name":"Person4","age":37}'
 [x] Received '{"name":"Person5","age":37}'
 [x] Received '{"name":"Person6","age":37}'
 [x] Received '{"name":"Person7","age":37}'
 [x] Received '{"name":"Person8","age":37}'
 [x] Received '{"name":"Person9","age":37}'
 [x] Received '{"name":"Person10","age":37}'

For more information on RabbitMQ view the link below.

http://www.rabbitmq.com/


http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware

How to Assign a Group of People to a Disposition Action using Oracle WebCenter

The following blog post comes from Fishbowl Senior Software Consultant Alan Mackenthun. Alan is Fishbowl’s resident records management expert and has been architecting such systems for over nine years. In working with a WebCenter customer, Alan was able to propose a solution that will enable the customer to configure WebCenter so that a group of users can be dynamically assigned to review dispositions. This isn’t a well-documented feature so we wanted to share it with the rest of the WebCenter community.

At its core records management is the management of the destruction of content when it’s no longer needed.  Usually, business processes dictate that someone review the content and approve destruction before the content is permanently deleted. Out of the box, you can either assign a specific user as a reviewer on a retention step or you could allow the default system reviewer alias to review dispositions, but there was no way to assign a group of users or to dynamically assign users.

Assigning a specific user may work in smaller organizations but even then, if a specific user is assigned and then they go on vacation or leave the company, all related disposition rules would have to be found and updated.  It was very difficult to make this work in a larger organization where document owners could be spread among separate business units or departments.

With the enhancement documented in the TKB referenced below, you can easily reference an alias in disposition rules.  To do so simply enter:

alias:<myAlias>

as the reviewer where “<my alias>” is the name of the alias you’d like to reference.  The real benefit here is that if you have Departmental Record Coordinators (DRCs) who review content in certain categories scheduled for destruction (disposition), you can assign the alias rather than named users.  Then if the DRC changes, the client only needs to update the alias, rather than all categories where that DRC was referenced.

Additionally, leveraging the ability to reference a script function gives you much more power.  Some categories of content, such as correspondence or memos, span all business units and departments.  On the other hand, there isn’t one person or group in an organization who should be approving the destruction of this content.  Instead, this feature allows you to reference a script function that can take the value of a business unit and/or department metadata field and map the value of this organizational unit to a user or alias who would be assigned as the reviewer. To do so simply enter:

script:<myScript>

as the reviewer where “<myscript>” is the name of the custom IdocScript function you’d like to reference (of course we at Fishbowl would be happy to help implement such a function if needed).

Oracle Support Document 1470906.1 (How to Request Approval Notification for a Group of People for a Disposition Action) can be found at: https://support.oracle.com/epmos/faces/DocumentDisplay?id=1470906.1

The post How to Assign a Group of People to a Disposition Action using Oracle WebCenter appeared first on C4 Blog by Fishbowl Solutions.

Categories: Fusion Middleware, Other

People are the problem can we stop pretending its technology

Steve Jones - Mon, 2013-02-04 06:00
A friend of mine the other day said an amazing thing I like coding in C++ I mean, seriously?  The land of friends, of people writing C code and debugging nightmares, had things got that much better, I mean I know there are some good threading libraries now but seriously, C++ is nice? All of the idiots code in Java, they don't know C++ And there we have the point.  Its not about what technology
Categories: Fusion Middleware