User.Get(username,connection) throws an exception

Aug 20, 2010 at 5:53 AM
Edited Aug 20, 2010 at 5:54 AM

Hi, there

I am doing some development around Trident. I would like to open Trident registry and add few things.

I used  Activity regActivity = Activity.CommonSearches.FindActivityInRegistry(activityFullName, presenter.RegistryHandle) to get an existing activity, it works well.

However, when I tried :

           Connection connection = SQLConnection.CreateTrusted("user", "Trident");
            User user = User.Get("nexus", connection);

it threw System.NullReferenceException: Object reference not set to an instance of an object.

at Microsoft.Research.DataLayer.Connection.get_TypeStoreMap() in D:\src\Trident\Trident\Product\DataLayer\Framework\DataLayerCommon\Connection.cs: line 185
at Microsoft.Research.DataLayer.NamedObject`1.Load(String nameConnection cObjectCreator creator) in D:\src\Trident\Trident\Product\DataLayer\Framework\DataLayer\NamedObjects.cs: line 105
at Microsoft.Research.DataLayer.User.Load(String nameConnection c) in D:\src\Trident\Trident\Product\Models\DataModel\codegen\class_User.cs: line 291
at Microsoft.Research.DataLayer.User.Get(String accountConnection c) in
Anyone knows the reason?
Many thanks
Aug 20, 2010 at 10:15 AM

Hi,

You need to call SR_connection.Init() before creating the connection object. In this call we initialize the search, storage and binding handlers.So, Sequence of steps would be:

 SR_Connection.Init()

Connection connection = SQLConnection.CreateTrusted("user", "Trident");
User user = User.Get("bai187", connection);
//Need to provide the Account name as the alias(not including the domain) of the username.

 
Ideal way for creating the connection object using the data layer. We need to follow the below mentioned steps.
1.       Call SR_Connection.Init() :- initialize the search, storage and binding handlers
2.       Create a ConnectionManager Object :- ConnectionManager uses the .configsources file to create the conenction. After installing Trident you can find .configsource file in the path %appdata%\Research\Trident\ConnStore-Application.configSources 
3.       Call ConnectionManager.PickConnection function with the Connection Behavior.
  ConnectionManager.ConnectionUI.AlwaysShowUI :- This will always shows UI to the user where he can select the connection and provide details.
  ConnectionManager.ConnectionUI.PromptIfNeeded :- This will prompt for a UI only if there is no default connection set. You can set a connection as default connection in the connection manager dialog.
  ConnectionManager.ConnectionUI.NeverShowUI :-
This will always not show Connection manager UI to the user. This works only if there is atleast one default connection specified.
 
Sample code snippet:
 << 
SR_Connection.Init();
ConnectionManager connMgr = ConnectionManager.Create(ConnectionManager.CancelBehavior.ThrowException);
Connection registryConnection = connMgr.PickConnection(ConnectionManager.ConnectionUI.AlwaysShowUI);
>> 
 Please let me know if this helped resolve your issue.

 Thanks,
Trident Support Team.

 

Aug 23, 2010 at 1:15 AM

It works. Many thanks.

An interesting thing is it does not work on my UnitTest, GetProviders return an empty list. However, it works well in my application.

BTW

We have found there are two %appdata%\Research\Trident\ConnStore-Application.configSources, one is under my account, the other is under "AllUsers".

We think that is because  TridentExecutionService run under System level, so ExectionService read the configuration file from "AllUsers" account,  are we right?

Cheers

 

 

 

 

 

 

 

Aug 23, 2010 at 6:43 AM

Another question is:

After we access the database, shall we manually call connection.close() or Trident datalayer disconnects it automatically?

for example:

if I use:

SR_Connection.Init()

Connection connection = SQLConnection.CreateTrusted("user", "Trident");
User user = User.Get("bai187", connection);

Shall I call connection.close() ?

Cheers

 

Aug 23, 2010 at 9:38 AM

Hi,

Trident datalayer does not close the connection automatically. We need to call Connection.Close() to disconnect from the underlying connection.

Once you’ve invoked Connection.Close(), you can use Connection.Open() to re-open the connection.

Please let us know if you need any other information.
Thanks,
Trident Support Team

Aug 23, 2010 at 10:53 AM
Edited Aug 25, 2010 at 6:48 AM

Hi,

 <<why there are 2 configsources>>.

Yes, The configsources under allusers is used by TridentExecutionService to connect to registry.

 

 <<why GetProviders return an empty list.>>

The design loading the providers is based on reflection. When the GetProvider function is called, it looks for the entire file name which starts from "Microsoft.Research.DataLayer.DataProviders.*.dll" in the current execution folder. If it not able to find any providers in the execution folder, it checks for AlternateProviderPath property. If it is able to find the providers in this path then it loads the providers.
If at all it is not able to find any provider(s) in both executable and alternate provider path. It throws a ProviderNotFound exception and exits the application.

The reason why it works well in your application is that you might have added reference to the DatalayerProvMSFT(Microsoft.Research.DataLayer.DataProviders.Microsoft.dll) into your project. So when the application is built the references are built and are copied to execution folder. So when the executable loads it will be able to find the provider dll in its execution path and will load the providers.

But when we are trying to run unit test case, the execution context of the might be different and the GetProviders function could not be able find any providers. You can try adding the reference to the provider to the project.
If by adding the reference does not work. Then we need to set the AllternateProviderPath of the connection to the path where the provider dll’s could be found.

You can set the AlternateProvider path using the property AlternateProviderLocation exposed in ConnectionManager class.
ConnectionManager.AlternateProviderLocation = “”; // Path where provider dlls are stored.

Please try the above methods and let us know if this resolved your issue. If not then can you please provide us with the unit test code which you’re trying to execute?

Thanks,
Trident Support Team

Aug 25, 2010 at 6:51 AM

Hi,

Can you please let us know if our reply answered you queries?

Thanks,
Trident Support Team.

Aug 25, 2010 at 11:14 PM

Yes, it does.

Many thanks

 

Aug 25, 2010 at 11:24 PM

Another question is:

I used Activity regActivity = Activity.CommonSearches.FindActivityInRegistry(activityFullName, presenter.RegistryHandle) .

I tried to find which category the activity is in, but it seems there is no category info in the instance of this actitvity.

What is the best way to get the category of an existing activity?

Cheers

Aug 26, 2010 at 3:50 PM

Hi,

We are looking into this and will get back to you shortly.

Thanks,

Trident Support Team

Aug 27, 2010 at 6:51 AM

Hi,

To get the category of the activity you need to use Activity.Namespace property in the Activity Model.
Please find below code snippet which retrieves the Activity (cove workflow. In Trident registry we assume workflow also to be an activity.)
Activity coveActivity = Activity.Load("Cove", registryConnection);

Once you have the activity instance then you can use the following code snippet to retrieve the category of the activity.
Namespace activityNamespace = coveActivity.Namespaces[0]

activityNamespace.Name will give you the name of the category. But this will not have the complete tree path of the category. To retrieve the full path of the category you need to use the below code.

static string GetParent(Namespace activityNamespace, string namespaceString)
{
    if (activityNamespace.HasParent)
    namespaceString = GetParent(activityNamespace.Parent, string.Format("{0}\\{1}", activityNamespace.Parent.Name, namespaceString));
 
    return namespaceString;
}

Above function will recursively go through all the parent categories and retrieve the final tree path of the current category in the format “cat1\cat1.1\cat1.1.1”. 

Please try the above steps to retrieve the category of an activity and let us know if this answers your question. 
Thanks,
Trident Support Team.

Aug 29, 2010 at 11:45 PM

Many thanks.

It soloved the problem.

Dec 1, 2011 at 11:17 PM

Hi

The ProvenanceInfos table contains a field called ActivityName but when you run the sample workflows the ActivityName is not populated with any value that is held in the Activitys table. 

Could you please tell me from where in the database (or other source) the ActivityName field is derived from.

Thanks

Dec 2, 2011 at 9:32 AM
Edited Dec 2, 2011 at 9:33 AM

Hi,

Thanks for your post.

The ActivityName in the ProvenanceInfos table denote the name of an Activity instance of a Job instance of a particular workflow. The ActivityName is
found in the ActivitySequence table in the Trident database. An ActivitySequence is actually a wrapper around an activity instance inside a running job. Since, a workflow
can have many running instances and each run is a job with a unique job id. Each job is consists of there own activity sequences.

Please let me know of any further query.

Regards,
Trident Support Team