January 2008 - Posts

Oracle SOA Suite 11g

I've playing around with the new preview of Oracle SOA Suite. Among the new features, Business Events is the most attractive to me and it can be considered Oracle's first iteration towards a complete Complex Event Processing platform based on different technologies of the SOA Suite. Additionally, the implementation of Service Component Architecture (SCA) as part of the SOA Composite Editor is definitely interesting although I am still not convinced of its applicability on Enterprise scenarios.

Posted by gsusx | 4 comment(s)
Filed under: , ,

RESTful services description languages

Steve Vinoski posted an interesting reflection about the use of description languages on RESTful services. I have to agree 200% with Steve, WSDL and 1.1 and simply horrendous. Although WSDL 2.0 drastically improves in the modeling aspects of the services it does not solve one of the fundamental problems of its predecessors which tightly couple web Services with RPC and object oriented models. This gets even worse when you are working with ESBs or Integration Servers that are highly dependent on WSDL, sometimes you get the impression you are writing a big object oriented programL.  However, I still think that some sort of description language is really beneficial in a lot of scenarios such as service-endpoint discovery, policy description, service management and versioning. On those scenarios, the use of languages such as RDF, WADL, Atom or even tools such as Power Point or Excel can provide a better and more flexible solution than WSDL.

More on modeling: SML 1.1

W3C has released new drafts of the Service Modeling Language specifications.

The Service Modeling Language (SML) Working Group has published the third Working Drafts of Service Modeling Language, Version 1.1 and Service Modeling Language Interchange Format Version 1.1. The former defines the SML 1.1, intended to model complex services and systems, including their structure, constraints, policies, and best practices. The latter defines the SML 1.1 interchange format, designed to ensure accurate and convenient interchange of the documents that make up an SML model.

Cleaning up BAM Activity Instances

One of the main challenges of Business Activity Monitoring(BAM) solutions is the control the lifecycle of the activities. This is especially critical in scenarios that involve activity continuations between different applications. Far too many times activities don't get completed affecting important BAM components such as aggregations, KPIs, etc. More importantly, keeping incomplete activities stored in the "ActivityName"_Active tables in the BAMPrimaryImport database can tremendously affect the performance of BizTalk BAM solutions. As part of the BizTalk server SDK we can find a SQL Server stored procedure that moves the incomplete activities from the Active tables to a new set of tables, the essence of this stored procedure is to add the incomplete state to the BAM Activity lifecycle creating a new table per BAM activity as well as its continuations and relationships. This stored procedure recycles individual activities and keeps the incomplete tables in the BAMPrimaryImport database. Although this approach works great, for a lot of scenarios makes sense to move the incomplete activities directly to the BAMArchive database keeping the BAMPrimaryImport database for storing live data. We can accomplish that with a few slight modifications to the same stored procedure highlighted in the following code. This stored procedure is intended to run in the BAMArchive database but it will poll the data from the BAMPrimaryImport database (notice the database prefix in some of the queries)

Create procedure CleanupUncompleteActivity @ActivityName nvarchar (128),

@ActivityId

nvarchar(128)=NULL,

@DateThreshold

datetime=NULL,

@NewTableExtension

nvarchar(30)=NULL

as

--stored procedure body

DECLARE @BAMDBPrefix nvarchar(500 )

DECLARE @QueryString nvarchar(4000 )

DECLARE @ActiveTableName sysname

DECLARE @ActiveRelationshipsTableName sysname

DECLARE @ContinuationsTableName sysname

DECLARE @DanglingActiveTableName sysname

DECLARE @DanglingActiveRelationshipsTableName sysname

DECLARE @DanglingContinuationsTableName sysname

SET @BAMDBPrefix= 'BAMPrimaryImport.dbo.'

SET @ActiveTableName = 'bam_' + @ActivityName + '_Active'

SET @ActiveRelationshipsTableName = 'bam_' + @ActivityName + '_ActiveRelationships'

SET @ContinuationsTableName = 'bam_' + @ActivityName + '_Continuations'

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

DECLARE @LockActivity nvarchar(128 )

SELECT @LockActivity = ActivityName

FROM BAMPrimaryImport.dbo.bam_Metadata_Activities WITH (XLOCK)

WHERE ActivityName = @ActivityName

EXEC sp_tables @table_name = #DanglingActivities

IF @@ROWCOUNT > 0 DROP TABLE #DanglingActivities

CREATE TABLE #DanglingActivities( ActivityID nvarchar(128) PRIMARY KEY)

SET @QueryString = N'INSERT INTO #DanglingActivities (ActivityID) SELECT ActivityID FROM ' + @BAMDBPrefix + 'bam_' + @ActivityName + '_Active'

IF (@DateThreshold is not NULL) OR (@ActivityId is not NULL)

BEGIN

SET @QueryString = @QueryString + ' WHERE'

END

IF (@DateThreshold is not NULL)

BEGIN

SET @QueryString = @QueryString + ' LastModified < N''' + CONVERT (nvarchar(50), @DateThreshold , 109) + ''''

IF (@ActivityId is not NULL)

BEGIN

SET @QueryString = @QueryString + ' AND'

END

END

IF (@ActivityId is not NULL)

BEGIN

SET @QueryString = @QueryString + ' ActivityID = N''' + @ActivityId + ''''

END

EXEC sp_executesql @QueryString

SELECT * FROM #DanglingActivities

SET @QueryString = N''

-- If the user gave a table extension, the dangling instances will be inserted

-- into that table.

IF (isnull(@NewTableExtension , '') <> '')

BEGIN

SET @DanglingActiveTableName = @ActiveTableName + '_' + @NewTableExtension

SET @DanglingActiveRelationshipsTableName = @ActiveRelationshipsTableName + '_' + @NewTableExtension

SET @DanglingContinuationsTableName = @ContinuationsTableName + '_' + @NewTableExtension

-- If the table for the dangling instances exist then insert into it

-- If the table does not exist, then create the dangling instances table

-- and then insert into it. SELECT INTO will do that.

-- Use [BAMArchive]

EXEC sp_tables @table_name = @DanglingActiveTableName

--USE [BAMPrimaryImport]

IF @@ROWCOUNT > 0

BEGIN

SET @QueryString = N'INSERT INTO ' + '[' + @DanglingActiveTableName + '] SELECT active.* FROM ' + @BAMDBPrefix + @ActiveTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ActivityID = dangling.ActivityID'

EXEC sp_executesql @QueryString

END

ELSE

BEGIN

SET @QueryString = N'SELECT active.* INTO [' + @DanglingActiveTableName + '] FROM ' + @BAMDBPrefix + @ActiveTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ActivityID = dangling.ActivityID'

select @QueryString

EXEC sp_executesql @QueryString

END

-- Now do what you did for the Active Instances table for the

-- ActiveRelationships table

EXEC sp_tables @table_name = @DanglingActiveRelationshipsTableName

IF @@ROWCOUNT > 0

BEGIN

SET @QueryString = N'INSERT INTO ' + '[' + @DanglingActiveRelationshipsTableName + '] SELECT active.* FROM ' + @BAMDBPrefix + @ActiveRelationshipsTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ActivityID = dangling.ActivityID'

EXEC sp_executesql @QueryString

END

ELSE

BEGIN

SET @QueryString = N'SELECT active.* INTO [' + @DanglingActiveRelationshipsTableName + '] FROM ' + @BAMDBPrefix+ @ActiveRelationshipsTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ActivityID = dangling.ActivityID'

EXEC sp_executesql @QueryString

END

-- And finally for the continuations table

EXEC sp_tables @table_name = @DanglingContinuationsTableName

IF @@ROWCOUNT > 0

BEGIN

SET @QueryString = N'INSERT INTO ' + '[' + @DanglingContinuationsTableName + '] SELECT active.* FROM ' + @BAMDBPrefix + @ContinuationsTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ParentActivityID = dangling.ActivityID'

EXEC sp_executesql @QueryString

END

ELSE

BEGIN

SET @QueryString = N'SELECT active.* INTO [' + @DanglingContinuationsTableName + '] FROM ' + @BAMDBPrefix + @ContinuationsTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ParentActivityID = dangling.ActivityID'

EXEC sp_executesql @QueryString

END

END

-- Remove the dangling instances from the Active Instances Table

SET @QueryString = 'DELETE FROM ' + @BAMDBPrefix + @ActiveTableName + ' FROM ' + @BAMDBPrefix + @ActiveTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ActivityID = dangling.ActivityID '

EXEC sp_executesql @QueryString

SET @QueryString = 'DELETE FROM ' + @BAMDBPrefix + @ActiveRelationshipsTableName + ' FROM ' + @BAMDBPrefix + @ActiveRelationshipsTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ActivityID = dangling.ActivityID '

EXEC sp_executesql @QueryString

SET @QueryString = 'DELETE FROM ' + @BAMDBPrefix + @ContinuationsTableName + ' FROM ' + @BAMDBPrefix + @ContinuationsTableName + ' as active INNER JOIN #DanglingActivities dangling ON active.ParentActivityID = dangling.ActivityID '

EXEC sp_executesql @QueryString

DROP TABLE #DanglingActivities

COMMIT TRAN

GO

As we mentioned previously, the stored procedure recycle individual activities. In case you need to cleanup multiple activities at the same time you can loop though the list of activities stored in the bam_Metadata_Activities table in the BAMPrimaryImport database. The following code illustrates that technique.

Create procedure CleanupUncompleteActivities @DateThreshold datetime =NULL,

@NewTableExtension

nvarchar(30)=NULL

as

declare

@activityname nvarchar(250)

declare

actcursor cursor

for

select ActivityName from BAMPrimaryImport. dbo.bam_Metadata_Activities

open

actcursor

FETCH NEXT FROM actcursor INTO @activityname

WHILE

@@FETCH_STATUS = 0

begin

execute CleanupUncompleteActivity @ActivityName= @activityname , @NewTableExtension= 'Uncompleted', @DateThreshold= @DateThreshold

FETCH NEXT FROM actcursor INTO @activityname

end

close actcursor

deallocate actcursor

 

You can download both stored procedure here but in any case we don't advice using these in production environments.

Mark Little on WS-* vs. REST

This is one of the best reflections I have ever read about the WS-* vs. REST debate. For the ones of you new to MEST, this is an complementary alternative to REST mostly evangelized by my friend and SOA guru Jim Webber
Posted by gsusx | 6 comment(s)
More Posts