Pages

Thursday, December 5, 2013

tcProvisioningOperationsIntf API Rejected and Pending Task example

The tcProvisioningOperationsIntf  inteface API being used to retrieve the Rejected and Pending Task, Retrying the Rejected Tasks, and Rejected Task Completed Manually in the Oracle Identity Manager repository.

Pre-Requisite:

Initial Setup.

Please follow the link and setup the OIM client environment to use to create the OIM Objects.


Client Code Setup

tcProvisioningOperationsIntf  API Usage:

1. Retrieving the Rejected and Pending tasks based on the Filter Criteria,
2. Retry the Rejected Tasks
3. Manually Completed the Rejected Tasks.
4. Manually Completed the Pending Tasks.

Tasks Needs to be Performed:

1.    Create the OIMClient Handle


OIMClient client= new OIMClient();
client.login(username,password.toCharArray());

2.    Get tcProvisioningOperationsIntf service object


tcProvisioningOperationsIntf provisioningServiceIntf = client.getService(tcProvisioningOperationsIntf.class);

3.  Retrieve the Rejected or Pending Tasks Based on The Resource Object and Task Name


// Resource Name. My Example Resource Name is AD User
String resourceName = "AD User";
// Failed Task Name. My Example Failed Task Name is Create User.
String taskName = "Create User" ;
String taskStatus = "Rejected"
Map<String, String> filter= new HashMap<String,String>();
filter.put("Objects.Name", resourceName);
filter.put("Process Definition.Tasks.Task Name",taskName);

// Failed Task Status. In my example failed task status is Rejected. If you need pending task, replace Rejected with Pending 
String taskStaus[]= new String[]{"Rejected"};

tcResultSet trs=provisioningServiceIntf.findAllOpenProvisioningTasks(filter,taskStaus);
List<Map<String,Object>> taskLists= new ArrayList<Map<String,Object>>();

int rowCount=trs.getRowCount();
if(rowCount >0){
    for(int i=0;i<rowCount ;i++)
    {
               trs.goToRow(0);
               Map<String,Object> map= new HashMap<String,Object>();
               map.put("Process Instance.Task Details.Key",trs.getLongValue("Process Instance.Task Details.Key"))
               map.put("Process Instance.Task Information.Target User",trs.getStringValue("Process Instance.Task Information.Target User"));
               map.put("Process Instance.Key",trs.getLongValue("Process Instance.Key"));
               map.put("Process Definition.Tasks.Key",trs.getLongValue("Process Definition.Tasks.Key"));
               map.put("Process Definition.Tasks.Task Name",trs.getStringValue("Process Definition.Tasks.Task Name"));

taskLists.add(map);
     }
    
}

4. Retry the Rejected Tasks

for(Map<String,Object> task : taskLists )
{
    long taskKey = (long) map.get("Process Instance.Task Details.Key");

   try
        {
            provisioningServiceIntf.retryTask(taskKey );
        } catch (tcAPIException e)
        {
            System.out.println(" - tcAPIException - Error" + e);
        } catch (tcTaskNotFoundException e)
        {
            System.out.println(" - tcTaskNotFoundException - Error" + e);
        }
}

5.    Rejected or Pending Task Completed Manually



for(Map<String,Object> task : taskLists )
{
    long taskKey = (long) map.get("Process Instance.Task Details.Key");

   try
        {
            provisioningServiceIntf.setTasksCompletedManually(new long[]{taskKey} );
        } catch (tcAPIException e)
        {
            System.out.println(" - tcAPIException - Error" + e);
        } catch (tcTaskNotFoundException e)
        {
            System.out.println(" - tcTaskNotFoundException - Error" + e);
        }
        catch (tcBulkException e)
        {
            System.out.println(" - tcBulkException - Error" + e);
        }
}


6.    Retrieving the Rejected Task History

for(Map<String,Object> task : taskLists )
{
    long taskInstanceKey = (long) map.get("Process Instance.Key");

   try
        {
          tcResultSet trs= provisioningServiceIntf.getProcessDetail(taskInstanceKey );
            int count=trs.getRowCount();
                for(int i=0;i<count;i++)
                {
                    trs.goToRow(i);
                    String taskName=trs.getStringValue("Process Definition.Tasks.Task Name");
                    boolean retryAllowed= trs.getBooleanValue("RETRYALLOWED");
                    long processTask=trs.getLongValue("Process Definition.Tasks.Key");
System.out.println( "taskName - "+taskName + " - retryAllowed - "+retryAllowed+ " - processTask - "+processTask);
                }
        catch (tcAPIException e)
        {
           System.out.println(e);
        }
        catch (tcNotAtomicProcessException e)
        {
           System.out.println(e);
        } catch (tcColumnNotFoundException e)
        {
            System.out.println(e);
        }
}

Saturday, November 23, 2013

weblogic.jms.common.JMSException: No failover destination.


Problem: The Weblogic throws  weblogic.jms.common.JMSException: No failover destination while provision or de-provision the user in Oracle Identity Manager in the Clustered environment.  The exception details as follows:


Error:

oracle.iam.identity.exception.UserModifyException: Uncategorized exception occured during JMS processing; nested exception is weblogic.jms.common.JMSException: No failover destination.
        at oracle.iam.identity.usermgmt.impl.UserManagerImpl.modify(UserManagerImpl.java:943)
        at oracle.iam.identity.usermgmt.api.UserManagerEJB.modifyx(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor2327.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
        at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at com.bea.core.repackaged.springframework.jee.spi.MethodInvocationVisitorImpl.visit(MethodInvocationVisitorImpl.java:37)
        at weblogic.ejb.container.injection.EnvironmentInterceptorCallbackImpl.callback(EnvironmentInterceptorCallbackImpl.java:54)
        at com.bea.core.repackaged.springframework.jee.spi.EnvironmentInterceptor.invoke(EnvironmentInterceptor.java:50)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
        at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy401.modifyx(Unknown Source)
        at oracle.iam.identity.usermgmt.api.UserManager_nimav7_UserManagerRemoteImpl.__WL_invoke(Unknown Source)
        at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:40)
        at oracle.iam.identity.usermgmt.api.UserManager_nimav7_UserManagerRemoteImpl.modifyx(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor8553.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:85)
        at $Proxy194.modifyx(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor2326.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
        at $Proxy399.modifyx(Unknown Source)
        at oracle.iam.identity.usermgmt.api.UserManagerDelegate.modify(Unknown Source)
        at edu.sfsu.trusted.db.recon.oim.SfsuTrustedReconOIMCrudDao.updateAttributes(Unknown Source)
        at edu.sfsu.trusted.db.recon.oim.SfsuTrustedReconOIMCrudDao.createUser(Unknown Source)
        at edu.sfsu.trusted.db.recon.SfsuTrustedReconWrapper.processRecord(Unknown Source)
        at edu.sfsu.trusted.db.recon.SfsuTrustedReconWrapper.processRecon(Unknown Source)
        at edu.sfsu.trusted.db.recon.SfsuTrustedDBReconciliation.execute(Unknown Source)
        at oracle.iam.scheduler.vo.TaskSupport.executeJob(TaskSupport.java:145)
        at sun.reflect.GeneratedMethodAccessor6935.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at oracle.iam.scheduler.impl.quartz.QuartzJob.execute(QuartzJob.java:196)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
Caused by: weblogic.jms.common.JMSException: No failover destination.
        at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110)
        at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSyncTran(DispatcherAdapter.java:53)
        at weblogic.jms.client.JMSProducer.toFEProducer(JMSProducer.java:1289)
        at weblogic.jms.client.JMSProducer.deliveryInternal(JMSProducer.java:796)
        at weblogic.jms.client.JMSProducer.sendInternal(JMSProducer.java:541)
        at weblogic.jms.client.JMSProducer.sendWithListener(JMSProducer.java:394)
        at weblogic.jms.client.JMSProducer.send(JMSProducer.java:384)
        at weblogic.jms.client.WLProducerImpl.send(WLProducerImpl.java:970)
        at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597)
        at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:574)
        at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:541)
        at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:471)
        at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:539)
        at oracle.iam.platform.async.messaging.MessageSenderImpl.send(MessageSenderImpl.java:75)
        at oracle.iam.platform.async.messaging.TaskRouter.route(TaskRouter.java:78)
        at oracle.iam.platform.async.messaging.MessagingExecutionService.submit(MessagingExecutionService.java:43)
        at oracle.iam.platform.async.impl.AsyncServiceImpl.submit(AsyncServiceImpl.java:75)
        at 


Cause:

1. OIM Adapter Time Out issue.

Symptoms:

1. Weblogic OIM Servers showed the Warning message in the Web Logic Console Server Pannel.
2. OIM throws SQL exceptions in the OIM Server log due to un available of the SQL jdbc connections.
3. Provision the user in target resource, but that resource info not available in the OIM Repository.
 
Solution:

Set the timeout functionality or Implement the Timeout functionality in the OIM resource adapters in the process task definition. For example resource adapters are Create User, Delete User, First Name Updated etc.



Wednesday, October 16, 2013

Exchange Online Source Anchor Update or Restore MailBox in Exchange Online Office 365

Process 2: Exchange Online Source Anchor Update or Restore MailBox in Exchange Online

This Process is necessary when the process 1.1 failed to move the user from Federated Domain to Managed Domain. The following tasks needs to be performed to update the Source Anchor Attribute.

 2.1 User Moving from Active State to Removable State in Exchange Online.

 2.1.1 Remove the User Windows Azure AD

 Remove-MsolUser -UserPrincipalName <User Principal Name> -force
 
        

 2.1.2 Remove the User from the Recycle Bin Windows Azure AD

 Remove-MsolUser -UserPrincipalName <User Principal Name> -force -RemoveFromRecycleBin

2.2 Linking Existing user from Removable State to Active State

If the process 2.1.1 and 2.1.2 Executed successfully, The user moved from Active State to Removable State in Exchange online and his Mail Box is Disconnected State in the Exchange Online. You need to wait 5 to 10 minutes to replicate the changes from Windows Azure AD to Microsoft Online. The following Commands needs to be executed to relinking the mailbox. They are

Get The Removable State Guid:

Get-RemovedMailbox UPN | Select Guid

Relink MailBox

New-MailBox -Name <Name> -RemovedMailbox <Guid> -FirstName <First Name> -LastName <Last Name> -DisplayName <Display Name> -MicrosoftOnlineServicesID <UPN>  -PrimarySmtpAddress <UPN> -ImmutableId <Immutable ID> -FederatedIdentity <Federated ID>
Federated is unique and should not contain any @ symbol. For example Federated is 123456789                   

2.3 Assign the Licenses to complete the Process

You need to wait 5 to 10 minutes to replicate the changes from  Microsoft Exchange Online to Windows Azure AD. The following Commands needs to be executed to assign the license. They are

 Update the Country Info to the User

 set-msoluser -UserPrincipalName <UPN> -UsageLocation "US" 
 Assign the License to the User
       
Set-MsolUserLicense -UserPrincipalName <UPN> -AddLicenses test:EXCHANGESTANDARD_STUDENT

Updating Immutable ID or Source Anchor or Federated ID in Office 365 or Exchange Online using Power Shell

Problem:

The On Premise users are not able to login in OutLook.com/MailDomain integrated with Federated Environment Such as AD FS or Shibboleth. The actual result is, the user always redirect to outlook.com login page after successfully authenticated against the on premise domain.

Cause:

Federated ID Is Missing in the Exchange Online or Immutable ID Attribute is Missing in the Azure AD.

Solution:


Two Ways to Update the Source Anchor Or Immutabe ID attribute using Windows Azure AD or Microsoft Exchange Online Command Lets.

Pre-Requisit

1. Install the Office 365 Command Lets
2. Install the Windows Power Shell


Process 1: Windows Azure AD Immutable ID Update in Federated Domain.

   In my examples I have used federated domain is test.edu and managed domain is test.onmicrosoft.com. You can replace with your own federated and managed domains before executing the command lets. The following tasks needs to be performed to update the Immutable ID in the Federated Domain.


    1.1 Move the User from Federated Domain to Managed Domain.
   
The following command needs to be execute to move the user from federated domain to non federated domain.

     Set-MsolUserPrincipalName -UserPrincipalName usrabc@test.edu -NewUserPrincipalName usrabc@testmain.onmicrosoft.com

    1.2. Update the Immutable ID in Managed Domain

The following command needs to be execute to update the Immutable ID in non federated domain.

 Set-MsolUser -UserPrincipalName usrabc@testmain.onmicrosoft.com -ImmutableId <Immutable ID>
    1.3. Move the User from Managed Domain to Federated Domain

The following command needs to be execute to move the user from managed domain to federated domain.

     Set-MsolUserPrincipalName -UserPrincipalName usrabc@testmain.onmicrosoft.com -NewUserPrincipalName usrabc@test.edu
 

Follow the Process 2 link to update the Source Anchor or Federated ID in Microsoft Exchange Online PowerShell

Continuation Process 2 



Friday, July 12, 2013

Encrypt and Decrypt OIM User Password


Encrypting and Decrypting the Oracle Identity Manager user password as follows

1. Create the config directory
Create the config directory and its required to encrypt and decrypt the password. The following way to create the config directory in your home.
mkdir config
mkdir config/fwmconfig

2. Copy the WeB Logic Config Files

Copy the WebLogic OIM Domain config files to the config/fmwconfig directory. The config files are located in $DOMAIN_HOME/config/fmwconfig.

xlserver.cert
xell.csr
usermessagingconfig.xml
system-jazn-data.xml
policy-accessor-config.xml
opss-resource-types.xml
logging-template.xml
keystores.xml
jps-config.xml
jps-config-jse.xml
default-keystore.jks
.xldatabasekey



3. Setup the Class Path

If your Decrypting the password at the web logic server level, the following class path needs to be set. They are

1. source $DOMAIN_HOME/bin/setDomainEnv.sh

2. export CLASSPATH=$OIM_ORACLE_HOME/server/platform/iam-platform-utils.jar:$WL_HOME/server/lib/wlfullclient.jar:$OIM_ORACLE_HOME/designconsole/ext/spring.jar:$OIM_ORACLE_HOME/designconsole/lib/oimclient.jar:$OIM_ORACLE_HOME/designconsole/ext/commons-logging.jar:$CLASSPATH

If your going to decrypt the user password using  eclipse IDE, set the following jar files into the eclipse classpath. They are

commons-logging.jar
fmw_audit.jar
glassfish.jaxb_1.0.0.0_2-1-12.jar
iam-platform-utils.jar
identitystore.jar
jacc-spi.jar
jps-api.jar
jps-az-api.jar
jps-az-common.jar
jps-az-management.jar
jps-az-rt.jar
jps-az-sspi.jar
jps-common.jar
jps-ee.jar
jps-internal.jar
jps-jboss-deployer.jar
jps-jboss.jar
jps-manifest.jar
jps-mbeans.jar
jps-patching.jar
jps-pep.jar
jps-platform.jar
jps-unsupported-api.jar
jps-upgrade.jar
jps-was.jar
jps-wls-trustprovider.jar
jps-wls.jar
jrf-api.jar
mdsrt.jar
oimclient.jar
opss-patch-wlst.jar
opss-patch.jar
oracle.security.jps.was.deployment.jar
oraclepki.jar
osdt_cert.jar
osdt_core.jar
osdt_xmlsec.jar
spring.jar
wlfullclient.jar





4. Execute the Sample Code 

The Sample Code is given below to encrypt and decrypt the password.
 
package dcrpwd;
import com.thortech.xl.crypto.*;

public class DecryptPassword
{
        public static void main(String[] args) throws tcCryptoException
        {
        String encryptPwd=
tcCryptoUtil.encrypt("testpwd123","DBSecretKey");
        System.out.println(encryptPwd);
                String decryptPwd = tcCryptoUtil.decrypt(
encryptPwd,"DBSecretKey" );
                System.out.println(
decryptPwd );
        }
}



java -Doracle.security.jps.config=<Location Of the jps-config.xml file> -DDOMAIN_HOME=<Specify the Before config directory>  dcrpwd.DecryptPassword
 

Final Sample Execution

java -Doracle.security.jps.config=c:/sample/config/fmwconfig/jps-config.xml -DDOMAIN_HOME=c:/sample  dcrpwd.DecryptPassword

Final Execution Output in eclipse:

I have highlighted the encryption and decryption string in bold font below.


May 27, 2014 11:31:16 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7f8bea70: display name [org.springframework.context.support.ClassPathXmlApplicationContext@7f8bea70]; startup date [Tue May 27 11:31:16 PDT 2014]; root of context hierarchy
May 27, 2014 11:31:16 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [META-INF/iam-spring-config.xml]
May 27, 2014 11:31:16 AM oracle.iam.platform.utils.SpringBeanFactory createBeanFactory
SEVERE: Instantiating Spring Bean Factory Failed.IOException parsing XML document from class path resource [META-INF/iam-spring-config.xml]; nested exception is java.io.FileNotFoundException: class path resource [META-INF/iam-spring-config.xml] cannot be opened because it does not exist
May 27, 2014 11:31:18 AM oracle.security.jps.internal.keystore.util.KeyStoreServiceUtil getMasterKey
WARNING: Failed to get/set credential in credstore.
May 27, 2014 11:31:18 AM oracle.security.jps.internal.keystore.util.KeyStoreServiceUtil getMasterKey
WARNING: Failed to get/set credential in credstore.
WLS ManagedService is not up running. Fall back to use system properties for configuration.
May 27, 2014 11:31:19 AM com.thortech.xl.crypto.tcCryptoHelper getKeyStoreFile
WARNING: Not able to fetch OIMPlatform instance for the given Platform. Hence defaulting to the OIMWebLogicPlatform
6013:DsDvxzJYlY47sP6WUaZNMw==
testpwd123

Thursday, May 23, 2013

Spring Frame Work .Net WCF Web Service

 I am using the Spring Frame Work .net to integrate the c# WCF Web Service. This web Service demonstrate the CRUD Operation capabilities and also spring dependency injection as follows.

1. Setting The Development Environment

 Installing the NuGet Extension

Please follow the NuGetInstall  link to install the nuget extension for visual studio 2010.

2 Creating the WCF Web Service Application

     Open the Visual Studio --> Click File --> New --> Project -->WCF and it will display the following screen.



Choose the WCF Service Application, and Enter the Name. In my example Name is MySampleWcfService and Click OK button. After Clicking the OK button and it will display the following directory structure.





3. Installing Spring and Dependency Libraries

Downloading the following Spring and dependency Libraries from the Nuget Repository.

Spring Packages

Spring.Core
Spring.Aop
Spring.Services

Spring Dependencies

Common.Logging
Common.Logging.Log4Net


Right Click on the References and Click Manage Nugget Packages and it will display the following screen.



Enter the Spring.Core in the search box and it will display the following screen.



Click Install Button and It will install the Spring.Core Package in the reference folder and it will display the following screen.



 Repeat the Same Steps for Spring.Aop, Spring.Services,Common.Logging and Common.Logging.Log4Net packages to install the references folder.


Reference Folder Structure

The packages are installed in the reference folder and package structure is shown below.




4.Developing Spring WCF Web Service

4.1 Rename The Service Files

Rename the meaning full names of the IService1.cs and Service.svc files.In My example I have rename from  IService1.cs to IAccountWcfService.cs and Service1.svc to AccountWcfService.svc file.

4.2 Develop the Data Contract

The service accept the data from the client. We are defining the data contract and it contains three fields. They are Id, Name, and AccountType. The sample data contact is shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace MySampleWcfService
{  
    [DataContract]
    public class Account
    {
        private string id;
        private string name;
        private string accountType;

        [DataMember]
        public string Id {
            set { this.id = value; }
            get { return id; }
        }
        [DataMember]
        public string Name
        {
            set { this.name = value; }
            get { return name; }
        }
        [DataMember]
        public string AccountType
        {
            set { this.accountType = value; }
            get { return accountType; }
        }

    }
}


4.2 Develop the Method Interceptor

The method interceptor is a AOP porgam and Intercept all the method request and logging the time. The Sample Program is given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AopAlliance.Intercept;
namespace MySampleWcfService
{
    public class SimplePerformanceInterceptor:IMethodInterceptor
    {
        private string prefix = "Invocation took";

        public string Prefix
        {
            get { return prefix; }
            set { prefix = value; }
        }

        public object Invoke(IMethodInvocation invocation)
        {
            string name = invocation.Method.Name;
            DateTime start = DateTime.Now;
            Console.WriteLine(name + "Start Time " + start);

            try
            {
              
                return invocation.Proceed();
            }
            finally
            {
                DateTime stop = DateTime.Now;
                Console.WriteLine(name + "End Time " + stop);
            }
        }

    }
}
4.3 Develop the Data Access Object

In my example I am going to store the Account object in memory using Dictionary Class. The Sample Class is Shown Below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MySampleWcfService.DAO
{
    public interface AccountMemDAO
    {
        void CreateAccount(Account account);
        void UpdateAccount(Account account);
        void DeleteAccount(string id);
        Account GetAccount(string id);

    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MySampleWcfService.DAO
{
    public class AccountMemDAOImpl : AccountMemDAO
    {
        private IDictionary<string, Account> data = new Dictionary<string, Account>();

        public void CreateAccount(Account account)
        {
            data[account.Id] = account;
           
        }

        public void UpdateAccount(Account account)
        {
            data[account.Id] = account;
        }

        public void DeleteAccount(string id)
        {
            data.Remove(id);
        }

        public Account GetAccount(string id)
        {
            if (data.ContainsKey(id))
            {
                return data[id];
            }
            else
            {
                return null;
            }
        }
    }
}


4.4 Develop the Service Object

Add the Service Methods into the IMySampleWcfService.cs file and the sample code is given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace MySampleWcfService
{
    [ServiceContract]
    public interface IAccountWcfService
    {
        [OperationContract]
        void CreateAccount(Account account);
        [OperationContract]
        void UpdateAccount(Account account);
        [OperationContract]
        void DeleteAccount(string id);
        [OperationContract]
        Account GetAccount(string id);
    }
}

4.5 Implement the Service Interface

The Sample Service Implementation is given below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using MySampleWcfService.DAO;
using MySampleWcfService.Exception;

namespace MySampleWcfService
{
    public class AccountWcfService : IAccountWcfService
    {
      
        private AccountMemDAO memdao;

        public void CreateAccount(Account account)
        {
            if(account==null)
            {
                throw new AccountWcfServiceException("The Account Object is Null");
            }
            if (account != null )
            {
                if(account.Id == null || account.Id.Trim().Equals(""))
                {
                    throw new AccountWcfServiceException("The Account Id Can Not be Null");
                }
            }
            Account acct = memdao.GetAccount(account.Id);
            if (acct == null)
            {
                memdao.CreateAccount(account);
            }
            else
            {
                throw new AccountWcfServiceException("The Account Id " + account.Id + " Already Exists.");
            }
        }

        public void UpdateAccount(Account account)
        {
            if (account == null)
            {
                throw new AccountWcfServiceException("The Account Object is Null");
            }
            if (account != null && (account.Id == null || (account.Id.Trim().Equals(""))))
            {
                throw new AccountWcfServiceException("The Account Id Can Not be Null");
            }
           
            Account acct = memdao.GetAccount(account.Id);
            if (acct != null)
            {
                memdao.UpdateAccount(account);
            }
            else
            {
                throw new AccountWcfServiceException("The Account Id " + account.Id + " Not Found.");
            }
        }

        public void DeleteAccount(string id)
        {
           
            if (id == null || id.Trim().Equals(""))
            {
                throw new AccountWcfServiceException("The Account Id Can Not be Null");
            }
           
            Account acct = memdao.GetAccount(id);
            if (acct != null)
            {
                memdao.DeleteAccount(id);
            }
            else
            {
                throw new AccountWcfServiceException("The Account Id " + id + " Already Exists.");
            }
        }

        public Account GetAccount(string id)
        {
            if (id == null || id.Trim().Equals(""))
            {
                throw new AccountWcfServiceException("The Account Id Can Not be Null");
            }

            Account acct = memdao.GetAccount(id);
            return acct;
        }

        public AccountMemDAO MemDao {

            set { this.memdao = value; }
        }
       
    }
}
 

4.5 Configuring the Web.Config File

4.5.1 Define the Spring Config Section

We need to define the section group and two sections. The section group name is spring and it is our root element for the spring configuration. The section name is context and holding the configuration resource info and another section name objects and it is being used to configure the spring beans.

<configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/>
      <section name="context" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/>
    </sectionGroup>
  </configSections>




4.5.2 Define the Spring Context Section

<context>
      <resource uri="config://spring/objects"/>
</context>

In the above uri specifying the config location defined in the sequence of  <configSections><sectionGroup>Section>. Please refer section 4.5.1

4.5.3 Define the Spring Objects Section

The following objects needs to be configured. They are

<object id="memdao" type="MySampleWcfService.DAO.AccountMemDAOImpl, MySampleWcfService" singleton="true"/>

      <!-- Defining the Service -->
<!-- Defining the Service -->
      <object id="serviceopr" type="MySampleWcfService.AccountWcfService, MySampleWcfService" singleton="true">
        <property name="MemDao" ref="memdao"/>
      </object>
      

     
      <!-- Defining the Service Operation-->

      <object id="serviceOperation" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut,Spring.Aop">
        <property name="pattern" value="^MySpringWcfApp.*"/>
      </object>
     
      <!-- Defining the Method Interceptor -->

<object id="perfAdvice" type="MySampleWcfService.SimplePerformanceInterceptor, MySampleWcfService">
        <property name="Prefix" value="Performance"/>
      </object>
           
      <!-- Defining the AOP -->

      <aop:config>
        <aop:advisor pointcut-ref="serviceOperation" advice-ref="perfAdvice" />
      </aop:config>
 


4.5.4 Sample web.config file

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
    </sectionGroup>
  </configSections>

  <spring>
    <context>
      <resource uri="config://spring/objects"/>
    </context>
    <objects xmlns="http://www.springframework.net"
             xmlns:aop="http://www.springframework.net/aop">

    
      <object id="memdao" type="MySampleWcfService.DAO.AccountMemDAOImpl, MySampleWcfService" singleton="true"/>
    
      <!-- Defining the Service -->
      <object id="serviceopr" type="MySampleWcfService.AccountWcfService, MySampleWcfService" singleton="true">
        <property name="MemDao" ref="memdao"/>
      </object>
    
      <!-- Defining the Service Operation-->

      <object id="serviceOperation" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut,Spring.Aop">
        <property name="pattern" value="^MySampleWcfService.*"/>
      </object>
    
      <!-- Defining the Method Interceptor -->

      <object id="perfAdvice" type="MySampleWcfService.SimplePerformanceInterceptor, MySampleWcfService">
        <property name="Prefix" value="Performance"/>
      </object>
    
    
      <!-- Defining the AOP -->
    
      <aop:config>
        <aop:advisor pointcut-ref="serviceOperation" advice-ref="perfAdvice" />
      </aop:config>
    
    
    </objects>
  </spring>
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
 
  <runtime>
 
       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 
            <dependentAssembly>
 
                 <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e" culture="neutral" />
 
                 <bindingRedirect oldVersion="0.0.0.0-2.1.2.0" newVersion="2.1.2.0" />
 
            </dependentAssembly>
 
       </assemblyBinding>
 
  </runtime>
</configuration>

The Sample Configuration is given below.

<%@ ServiceHost Language="C#" Debug="true" Service="serviceopr" Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>

6. Compile the Web Service
Click Build --> Build Solution. It will Compile the Source Files.
7. Deploy the Web Service.
Click the Build --> Click Publish MySampleWcfWebService and it will display the following screen.
 
Select or Import Publish Profile combo box --> New and It will display the following screen
 
After Entering the profile name and click Ok button and it will display the following screen.
 
 
Enter Service URL and Site/Application Name. In my example service name is host name(localhost) and site name is Default Web Site/MySampleWcfService. Click Next Button and it will display the following screen.




Click Next Button and It will display the following screen.


Click Publish Button and It will deploy the Web Service in the IIS Server.

After successfully deploy the web service and it will shown the following output in the console. 




8. Verifying the Deployed Web Service in IIS

Open the IIS Manager and verify our web service is deployed. The Web Service is Deployed Successfully and it will shown the following screen shot.




Right Click the MySampleWcFService and Click Switch to Content View and It will Display the following screen.



Right click on the AccountWcfService.svc file and Select Browse and it will display the following screen.



9. Testing the Web Service

Open the WcfTestClient.exe file and it is available in the location of "c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe". After clicking the WcfTestClient.exe file and it will show the following screen.





Click File --> Add Service and It will display the following screen.




 
Enter the Service End oint Url and Click OK Button and It will fetch the service operation definitions as shown below.


Click CreateAccount and it will display the following screen.


Enter Id,Name,AccountType and Click Invoke Button. It will create the Account in Memory.  In My Example i have given id is 123, Name is TestName and AccountType is CreateAccount. We will verify using the GetAccount passing the id. Please click the GetAccount and it will display the following screen.




Enter Id is 123 and It will fetch the  stored account details and the detailed screen shot given below.



Please repeat the steps for Update Account and Delete Account.

References:


Best Of Luck