Thursday, February 2, 2012

Troubleshooting workflow visualization in SharePoint 2010

SharePoint 2010 introduced a very nice feature that enables visual representation of workflow status on the workflow status page using Visio diagrams hosted in a Silverlight web part.

Recently I’ve created a simple declarative workflow in SharePoint Designer 2010 and configured it to display workflow visualization:

image

I then published and started the workflow and went to the workflow status page hoping that I would see the visual of the workflow status. Instead, all I saw was the error message “The server failed to process the request.”:

image

First I went to Central Administration>System Settings>Mange services on server and checked if the Visio Services were running:

image

So all fine there. Next step: go to Central Administration>Application Management>Service Application Association to check if the Visio Services was part of the Service Application Proxy associated with the affected web app:

image

No problem there either, so next I checked the ULS log to see if there are any errors. And indeed, this is the stack trace I found:

System.Data.SqlClient.SqlException: Cannot open database "WSS_Content_Team" requested by the login. The login failed.  Login failed for user 'CONTOSO\sp_serviceapp'.     
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Microsoft.SharePoint.Utilities.SqlSession.OpenConnection()
at Microsoft.SharePoint.Utilities.SqlSession.ExecuteReader(SqlCommand command, CommandBehavior behavior, SqlQueryData monitoringData, Boolean retryForDeadLock)
at Microsoft.SharePoint.Utilities.SqlSession.ExecuteReader(SqlCommand command, Boolean retryForDeadLock)
at Microsoft.SharePoint.Utilities.SqlSession.ExecuteReader(SqlCommand command)
at Microsoft.SharePoint.Upgrade.SPDatabaseSequence.GetVersion(SPDatabase database, Guid id, Version defaultVersion, SqlSession session, SPDatabaseSequence sequence)
at Microsoft.SharePoint.Upgrade.SPDatabaseSequence.get_SchemaVersion()
at Microsoft.SharePoint.Upgrade.SPSequence.get_IsBackwardsCompatible()
at Microsoft.SharePoint.Upgrade.SPUpgradeSession.IsBackwardsCompatible(Object o, Boolean bRecurse)
at Microsoft.SharePoint.Administration.SPPersistedUpgradableObject.get_IsBackwardsCompatible()
at Microsoft.SharePoint.Administration.SPPersistedUpgradableObject.ValidateBackwardsCompatibility()
at Microsoft.SharePoint.SPSite.PreinitializeServer(SPRequest request)
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
at Microsoft.SharePoint.SPWeb.BypassUseRemoteApis()
at Microsoft.Office.Visio.Server.GraphicsServer.FileHandler.GetFileContents()
at Microsoft.Office.Visio.Server.GraphicsServer.FileHandler.Open(Boolean readOnly)
at Microsoft.Office.Visio.Server.GraphicsServer.FileHandler.OpenFile(DiagramRequest request, Boolean needXml)
at Microsoft.Office.Visio.Server.GraphicsServer.Core.VectorizeDiagram()
at Microsoft.Office.Visio.Server.GraphicsServer.Core.get_VectorDiagram()
at Microsoft.Office.Visio.Server.GraphicsServer.VisioGraphicsService.GetVectorDiagram(VectorDiagramRequestContract vectorDiagramRequest)
at Microsoft.Office.Visio.Server.GraphicsServer.VisioGraphicsService.VectorDiagramCallback(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)


So it seems that the service account under which my Visio Services are running (CONTOSO\sp_serviceapp) couldn’t connect to my content database (WSS_Content_Team). I went to the SQL Server Management Studio and indeed, the CONTOSO\sp_serviceapp did not have permissions in my content database. So I went ahead and added the CONTOSO\sp_serviceapp to the dbo role in the content database:

image

Went back to my workflow status page and did Ctrl+F5 to reload, but still got the same error as before: “The server failed to process the request.”.


Back to the ULS log. This time a different exception popped up:


Failed to generate Vector diagram for file http://team.contoso.dev/sites/test/Workflows/Engagements Workflow/Engagements Workflow_V1.vdw Error : 
Microsoft.SharePoint.Upgrade.SPUpgradeCompatibilityException: There is a compatibility range mismatch between the Web server and database "WSS_Content_Team", and connections to the data have been blocked to due to this incompatibility. This can happen when a content database has not been upgraded to be within the compatibility range of the Web server, or if the database has been upgraded to a higher level than the web server. The Web server and the database must be upgraded to the same version and build level to return to compatibility range.
at Microsoft.SharePoint.Administration.SPPersistedUpgradableObject.ValidateBackwardsCompatibility()
at Microsoft.SharePoint.SPSite.PreinitializeServer(SPRequest request)
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
at Microsoft.SharePoint.SPWeb.BypassUseRemoteApis()
at Microsoft.Office.Visio.Server.GraphicsServer.FileHandler.GetFileContents()
at Microsoft.Office.Visio.Server.GraphicsServer.FileHandler.Open(Boolean readOnly)
at Microsoft.Office.Visio.Server.GraphicsServer.FileHandler.OpenFile(DiagramRequest request, Boolean needXml)
at Microsoft.Office.Visio.Server.GraphicsServer.Core.VectorizeDiagram()
at Microsoft.Office.Visio.Server.GraphicsServer.Core.get_VectorDiagram()
at Microsoft.Office.Visio.Server.GraphicsServer.VisioGraphicsService.GetVectorDiagram(VectorDiagramRequestContract vectorDiagramRequest)


Huh? The error message implies that there is a potential compatibility problem with my database, which typically occurs when you attach a SharePoint 2007 database and attempt to use 2010 features in it before upgrading it to 2010. However, this was a brand new 2010 database, so this couldn’t be the case.


Then I remembered the golden rule: never touch SharePoint databases directly.


Never.


There’s always a better way. In my case I had given the dbo rights on the content DB to the service account directly, but that was obviously not enough to make it work. Looking for the solution, I stumbled upon this article and found and executed the following PowerShell snippet to provide the necessary DB access rights to the service account:



   1: $webApp = Get-SPWebApplication "http://team.contoso.dev"
   2:  
   3: $webApp.GrantAccessToProcessIdentity("CONTOSO\sp_serviceapp")

Went back to my workflow’s status page, did a refresh and voila:


image


Note:


You might need to restart the Visio Services from Central Administration and do an iisreset if it still doesn’t work.

The obligatory first post.

Ok, I've started a blog. Let's see how long it lasts.