Archives

Archives / 2008 / January
  • 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.

    Read more...

  • 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.

    Read more...

  • 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.

    Read more...

  • 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.

    Read more...