Feeds:
Posts
Comments

Posts Tagged ‘ECM’

We are working on a demo application and we had a need to retrieve the comments on an activity in a workflow. Today morning one of my colleagues approached me regarding the same. I was not of much help to her. Few hours later she figured out that the comments were to be retrieved from the package (dmi_package). I was disappointed because I realized that I knew it but it was lost somewhere in my mind. I decided to once again explore the comments in a workflow.

I remember that the comments are stored as objects of type dm_note. I fired a simple select query on my docbase for retrieving all the objects of type dm_note.

SELECT * FROM dm_note

While scrolling through the result, I noticed that the column for a_content_type was displaying the value ‘crtext’ for all the results. The content type ‘crtext’ is used for the txt/notepad documents and I recalled immediately that the comments are stored in the file store as txt files.
Thus, in a way dm_note is similar to dm_document. I was eager to check the supertype of dm_note. I used the following query for the same.

SELECT super_name FROM dm_type WHERE name = 'dm_note'

The result was dm_sysobject. I was on the right track. Even the txt file for dm_note should be stored as dmr_content. I was happy to find that the i_contents_id of a dm_note object was of the format ’06XXXXXXXXXXXXXX’. I used the same query to get the content file path on the file system which I have mentioned in my earlier post regarding dmr_content.

EXECUTE GET_PATH FOR '06XXXXXXXXXXXXXX'

I got the following file path as a result:
D:\Documentum\data\TrainingBase\content_storage_010000065\800\60\3c.txt

I navigated to the mentioned file path on my file store and as expected 3c.txt had the comments that were entered in the workflow task.

As I knew that the attached documents in a workflow are actually linked to the package which in turn is linked to workflow, it was quiet logical that even the comments (the dm_note objects) are linked to the package. I found that the dmi_package has an attribute called r_note_id and it was repeating. This is the attribute which links the comments with the package. I checked the Object Relation diagram to confirm it.

dm_note

dm_note

I was correct in saying that the comments are linked to package much in a similar way as attached documents are linked to it.

I realize that I have left a gap regarding the linkage of documents in a workflow (package) and workflow in general. I will try to bridge it in my next post.

Advertisements

Read Full Post »

This query is raised by many people who read my earlier posts on Aliases. Why do I need more than one Alias Set? Let me try to answer this question. As per my understanding of Aliases I can clearly visualize its use and benefit while using multiple Alias Sets. Most of the people who raised this question had a mindset that the Alias will make their work easier as it will act as a place holder and they will be able to replace the value and use the same Alias set again and again. I had tried the same as mentioned in my first post on Alias.
I had created an Alias Set and an ACL Template using the Alias. This ACL Template was applied on a document. The Alias was resolved and the permission defined in the ACL Template was granted to the user defined in the Alias. Later when I updated the Alias value with a new user name and applied it on a new document, the new user was granted the permissions in the ACL Template. The behavior was as per expectation. What about the permission on the first document? It was found that the user name in the permission set of the first document was updated as per the Alias Set. In other words, I was not able to grant permissions to two different users on two different documents using one Alias Set. The change in the Alias value was reflected even in the Permission Set on the old document. In this case there was no other option but to use more than one Alias Set. More precisely I needed as many Alias Sets as the number of users.

Why?
If I don’t use Alias Sets and ACL Template and try achieving the same situation then I need to create ten different ACL for ten different users. While using Aliases I need one Permission Set Template and ten Alias Sets. So, there is no reduction in the efforts as such. The benefit can be seen only while managing the ACL. In the previous case if the permission has to be changed (lets say from read to write), we need to update all ten ACL. In the later case updating the ACL Template will give us the desired result. Just to note that the ACL cannot be updated through DQL if you thought that all the ten ACL can be updated through DQL by using an appropriate Where condition. As the number of ACL grows, the ease in managing the permission using ACL Template becomes increasingly prominent.

When?
Does that mean I can use ACL Templates and Aliases in every case? The condition being that all the users need the same permission on the respective document. In the above case all the ten users have the same permission on the respective document. ACL Templates and Aliases can be really helpful in granting permissions to specific users who can be very large in numbers as compared to limited number of groups.

How?
In a recent implementation I have used ACL Templates and Aliases to grant permission to user and his superiors in the organization hierarchy. I have one Alias Set per user and it defines his superiors at various levels through different Aliases. The Alias Sets are created, associated and updated through a TBO. The same Aliases are also used in the workflow to decide the performer of various activities. In absence of the Alias Set I would have to fetch the users’ superiors and set them as performers of various activities in the workflow using a DFC code. As evident, Aliases have helped me in more than one ways.

Related Articles:

Read Full Post »

Here is a new attempt to implement Alias Set and ACL Template in a way that can be more meaningful. The Major drawback in the previous implementation was that the Alias Set was associated with a single user. As the ACL Template was always being assigned by the same user, every time Alias was resolved to the same value unless the user was associated with a new Alias Set.

Alias Sets can be used in a much better way if the Alias can be resolved to different values at different instances. One of the easiest ways to achieve it is by associating the Alias Set directly with the Sysobject. If it was followed in previous case, different ACLs could have been applied to different Sysobjects while using only one ACL Template and multiple Alias Sets.

The attribute of dm_sysobject that is responsible for its relation with an Alias Set is r_alias_set_id. It stores the r_object_id of the Alias Set. It appeared to me that the only possible (and meaningful) way of associating a Sysobject and an Alias Set should be through DFC. I started my search for a method of IDfSysObject that can be used for the purpose. But I failed myserably in my effort. I couldn’t find a method as per my expectation. Finally I resolved to my ultimate rescuer, Google. I found a post regarding Permission Set Template by Johnny. In his comments he has mentioned, “I manually set the r_alias_set_id directly against the object that I am assigning the PST to.” I was surprised at the ease and simplicity of his statement. I was trying to achieve the same. I had an understanding that the r_ attributes are read-only with r_version_label being an exception. Still I descided to try the setString method of IDfSysObject.

The Field Setup:

Five Users created: TestUser1, TestUser2, TestUser3, TestUser4, TestUser5.
Five Alias Sets: TestUserAlias01, TestUserAlias02 …. TestUserAlias05.
An ACL Template: TestACLTemplate

Each Alias Set has a corresponding user name as the Alias Value. The process of creating the set-up was similar to that in the earlier case.

The Game:
Following is the fragment of DFC code used. Five objects of type dm_document are created, they are associated with corresponding Alias Sets and finally the ACL Template is applied on the newly created objects.

***************************************************************

for(int i=1; i<= 5; i++){
IDfDocument document = (IDfDocument) dfSession
.newObject("dm_document");
if (document != null) {
document.setObjectName("TestAliasObject_00"+i);
document.setContentType("pdf");
document.setFile("C:Test.pdf");
document.link("/dmadmin");
// can be a business logic
document.setString("r_alias_set_id",
dfSession.getObjectByQualification
("dm_alias_set where object_name = "
+"'TestUserAlias0"+i+"'")
.getObjectId().toString());
document.setACLName("TestACLTemplate");
document.setACLDomain("ASSAPArchive");
document.save();
}
}

***************************************************************

The main concern was the highlighted statement. Before reading Johnny’s post there was no reason to believe that it can ever work.

It was established that the understanding regarding r_ attributes was a misconception. At the least there is one more attribute which is an exception to the rule. Updating r_alias_set_id through DQL was also successful.

Anyway, my part in the game was over and it was time to verify the results.

Result:

testaliasobjects

Benefit:
Consider a case where the permission of all the users has to be changed from Write to Version. In the current set-up it can be achieved by updating only the Template Permission Set. If instead ACLs were used, all of them would have to be updated individually.

Related Articles:

Read Full Post »

Few days back I had read the chapter on Aliases. Since then I was eager to play with them. Ultimately I got my game plan ready. It was not a full-fledged plan which could give me a result but it was good enough for an initiative. I like flexible plans so that I can make changes as and when I feel, according to my comfort. Okay, lets stop the gossip and let the game start.

Setting up the field:

I will be using ACL Template to play with Aliases. As I am using ACL Template, I will also be requiring a set of users and objects.

As a first step I use the following DQL query to create a user.

create dm_user object
set home_docbase = 'ASSAPArchive',
set user_os_domain = 'infch02088',
set user_name = 'TestUser1',
set user_os_nam e= 'TestUser1',
set user_source = 'inline password',
set user_password = 'TestUser1'

Similar DQL queries were used to create four more users TestUser2, TestUser3, TestUser4 and TestUser5.

I like users to be part of a group.

CREATE GROUP TestUserGroup
WITH MEMBERS
(SELECT user_name
FROM dm_user
WHERE user_name like 'TestUser%')

No need to worry; there are no additional users with similar name in my repository. Now I have a group named TestUserGroup and it has five members named TestUser1,…..TestUser5.

Till here it was pretty easy. Isn’t it? But the game has not started yet. I am just arranging the players at their respective positions.

Before I create the ACL Template, I will need the Alias Set with the Alias that has to be used in the ACL Template.

CREATE dm_alias_set OBJECT
SET object_name = 'TestUserAlias';
UPDATE dm_alias_set OBJECTS
APPEND alias_name = 'TestUser',
APPEND alias_value = 'TestUser1',
APPEND alias_category = 1,
APPEND alias_usr_category = 1,
APPEND alias_description = 'Testing alias in ACL Template'
WHERE object_name = 'TestUserAlias';

Now I can go ahead with the creation of ACL Template. ACL Template is not same as ACL. It is actually a kind of ACL where aliases are used in place of users/groups. When such an ACL is applied to an object at runtime, the content server resolves the alias and creates a custom ACL with the resolved users/groups and the permissions in the ACL Template. ACL Template can be recognized as objects of dm_acl with acl_class = 1.

Below is the screen shot for the ACL Template created through Application Builder.newacltemplate_1

The field is set now.

Users : TestUser1, TestUser2, TestUser3, TestUser4, TestUser5.

Group : TestUserGroup

Alias Set Name : TestUserAlias

Alias Name : TestUser

ACL Template : TestACLTemplate

The Game Begins:

Let me go ahead with objects (of type dm_document) creation and apply the Template ACL to them.

CREATE dm_document object
SET object_name = 'TestObject1',
SET acl_name = 'TestACLTemplate'
SET acl_domain = 'ASSAPArchive'
LINK '/dmadmin'

FOUL!!!!!!!!!!!

[DM_QUERY_F_UP_SAVE]fatal:  “UPDATE:  An error has occurred during a save operation.”

[DM_POLICY_E_AS_NO_ALIAS_SET_USER]error:  “No default alias set found for user dmadmin. The following alias sets were searched: sessionconfig, user, user’s default group, server config, and policy (if applicable)”

Let me associate the Alias Set with the user, else there is no way the Alias can be resolved.

UPDATE dm_user OBJECT
SET alias_set_id =
(SELECT r_object_id
FROM dm_alias_set
WHERE object_name = 'TestUserAlias')
WHERE user_name = 'dmadmin'

The Alias Set is associated with the user. Once again I use the previously used DQL query for creating a dm_document object and applying the ACL Template to it. This time I was successful.

Lets check the permissions in the property page of the newly created object. A new custom ACL named dm_450003f080001517_80001100 is created and assigned to the object. It should be noted that the r_object_id of the ACL Template is 450003f080001517. Below is the screen shot of the property page. The new ACL has the resolved user name from the Alias Set.

testuser1permission_11

Second half:

The first part of the game is over. Now I need to change the user in the Alias set and check whether the change is reflected in the permissions of the new object.

UPDATE dm_alias_set OBJECT
SET alias_value[0] = 'TestUser2'
WHERE object_name = 'TestUserAlias'

The change in Alias Set is reflected in the object’s permission. So, a successful implementation of Alias Set is achieved. But a single Alias Set is not of much help in a practical scenario. Let me create one more Alias Set.

CREATE dm_alias_set OBJECT
SET object_name = 'TestUserAlias1'
APPEND alias_name = 'TestUser',
APPEND alias_value = 'TestUser1',
APPEND alias_category = 1,
APPEND alias_usr_category = 1,
APPEND alias_description = 'Testing alias in ACL Template'

The newly created Alias Set is now applied to the user dmadmin. Next time I created an object named TestObject2 and applied the ACL Template to it; the resolved user was as per the new Alias Set. Now I have two objects on which I had applied the same ACL Template and both have different users in their custom permission sets.

Analysis:

This situation is achieved because the Alias Set associated with dmadmin was changed before applying the ACL Template to the new object. Am I going to change the Alias set of dmadmin every time I apply the ACL Template to an object? That doesn’t appear to be a good idea. Further If due to some reason I need to reassign the ACL Template to the older object I may be into serious trouble.

Result:

The Alias Set was created and implemented along with the ACL Template. But the approach was not satisfactory for the practical purposes. A new plan has to be devised. Let me take a break now. I will be back with the new plan soon.

Related Articles:

Read Full Post »

Do check the comments for clarification.

I have a BIG DOUBT (appears big to me) and my only intention of writing this post is to get a clarification. So, if you are looking for some knowledge gain over here, you may instead be inviting a BIG PAIN in your head. I am inviting only contributors who can help me clarify MY BIG DOUBT. Anyone else reading this article will be doing so at his own risk.

Okay. Let me start now.
I was reading the first chapter, ECM Basics of Pawan Kumar’s book on Documentum Content Management Foundations and came across the following.

The term Content Server is used in two contexts – the Content Server software that is installed and resides on the file system and the Content Server instance, which is the running process that resides in memory and serves content at runtime. However there is little chance of confusion since the usage is often clear from the context and the term Content Server is typically used without additional qualification (software or process/instance).
A Content Server instance is dedicated to and manages only one repository. However, we will see later in architecture discussion that multiple Content Server instances can be dedicated to the same repository. This is typically done for performance reasons where the multiple Content Server processes divide up the load for serving content from the same repository.

Pawan is pretty clear in what he has mentioned. I got the doubt while relating it to the practical usage.

In practice while creating an environment setup we first install Content Server on a server (after installing database) system and then we create repositories. We can have multiple repositories. What we have now is one installation of Content Server Software and more than one repository.
Once all the installation and configuration process is over (including Content Server, Application Server, Webtop/Custom Application) and the application is ready for use, we can connect to the application through a browser. We get a login screen where we get the drop-down having the repository names to choose from. We can select any repository on the login screen and connect to it after authentication.

Now the thing which I am wondering about: As per the book the repositories have dedicated Content Server Instances. So if we have two repositories, we should as well be having two Content Server Instances which are actually running Processes/Programs. Where can I see these instances? When are they created? How can I make two Content Server Instances to serve single repository?

I don’t have an answer to these questions.
After a lot of brain storming I could think of starting/stopping of docbases using Documentum Server Manager. By starting a docbase we are indeed starting a process or a program. This program for sure is dedicated to the particular repository. So, shall it be correct if I say that by starting a docbase through Server Manager, I am actually starting a Content Server instance?

….BOOOOM….

I am sorry if it is a NON-SENSE of a very HIGH LEVEL, but this was the best I could think of. Even if I assume the statement to be true, how am I going to make an additional Content Server instance to serve the same repository? This is creating a much bigger pain in my head. I am confused and I am sure I am creating pain in my audience’s head too. Just wondering whether docbroker is also involved somewhere in the scene?

Let me stop here. This pain is becoming unbearable and I want to get rid of it.
Looking forward for some clarification. Any kind of help in this regard will be highly appreciated.

Uttkarsh's most interesting photos on Flickriver

Read Full Post »

Few days ago my friend asked me a dql query. He wanted to have a list of all the documents and their folder paths in the repository.

It didn’t appear to be a tough one. I knew that the i_folder_id of dm_document is mapped with the r_object_id of the dm_folder to which the document is linked to. A document can be linked to multiple folders and that explains why this i_folder_id is a repeating attribute. The dm_folder has another repeating attribute r_folder_path which stores the folder path of that particular folder. The reason for r_folder_path being repeating is same as that for i_folder_id in case of dm_document.

I told him this dql to get the folder path of all the documents.

SELECT r_folder_path
FROM dm_folder
WHERE r_object_id in
(SELECT distinct i_folder_id
FROM dm_document)

He didn’t look happy enough. What he actually wanted was a list of documents with the folder path. I told him that it is not a problem; we can put a join and get the object_name from dm_document.

SELECT doc.object_name,fol.r_folder_path
FROM dm_document doc, dm_folder fol
WHERE any doc.i_folder_id = fol.r_object_id

The query looked very simple to me. He seemed to be happy and he told he will try it out. I was happy that I have given him a solution. I was a bit surprised when he told me that he was getting an error while executing this query. I didn’t expect this. The error was:

    :[DM_QUERY2_E_REPEAT_TYPE_JOIN]error: “Your query is selecting repeating attributes and joining types.”

The above query works fine if I select only doc.object_name; but it was not allowing me to select fol.r_folder_path which is a repeating attribute. The conclusion was that a repeating valued attribute cannot be selected in a normal query which uses repeating valued attribute in a join. It can be achieved by using DQL Hints mentioned later. But this friend of mine needs both Document Name and Folder Path together. I asked him to write a dfc code which gets all the documents, finds their folder path and writes this information to a file. But my friend is a real lazy guy. The bad part being that I am also no different.

I thought a lot and in the end I got an idea. I asked him to fire a query on the RDBMS tables. The object types are represented as _s and _r tables in RDBMS for their single and repeating valued attribute respectively. The query has to be fired on dm_document_s, dm_document_r, dm_folder_s and dm_folder_r tables.

So, the new query which I formed was:

SELECT doc_s.object_name,fol_r.r_folder_path
FROM dm_document_s doc_s, dm_document_r doc_r, dm_folder_r fol_r
WHERE doc_s.r_object_id = doc_r.r_object_id
AND doc_r.i_folder_id = fol_r.r_object_id

But when I fire this query on my docbase I again got an error.

    :[DM_QUERY2_E_TABLE_NOT_FOUND]error: “The database table or view was not found in the database. Error from the database was: ‘ — The database object is invalid — STATE=S0002, CODE=208, MSG=[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name ‘dbo.dm_document_r’.'”

I realized that there is no such table called dm_document_r as dm_document doesn’t have any repeating attribute of its own. But in that case from where should I get the value for i_folder_id? If i_folder_id is not an attribute of dm_document then it should be inherited from dm_sysobject. Isn’t so?

So I had my new dql:

SELECT doc_s.object_name,fol_r.r_folder_path
FROM dm_document_s doc_s, dm_sysobject_r doc_r, dm_folder_r fol_r
WHERE doc_s.r_object_id = doc_r.r_object_id
AND doc_r.i_folder_id = fol_r.r_object_id

I was so confident. This is the ultimate query which will get me the result. When I fired this query I got the following result.

    :[DM_QUERY_E_CURSOR_ERROR]error: “A database error has occurred during the creation of a cursor (‘ STATE=S0022, CODE=207, MSG=[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name ‘object_name’.’).”

How could I forget that object_name is also an attribute of dm_sysobject. Actually the dm_document_s has just one attribute and that is the r_object_id. As a matter of fact dm_document doesn’t have any attribute of its own. Then what is the use of having the object_type dm_document? I leave this question to be answered by you. This has to be my final query.

SELECT doc_s.object_name,fol_r.r_folder_path
FROM dm_sysobject_s doc_s, dm_sysobject_r doc_r, dm_folder_r fol_r
WHERE doc_s.r_object_id = doc_r.r_object_id
AND doc_r.i_folder_id = fol_r.r_object_id

Ultimately I got the result without any errors. But I wasn’t too happy. Many records in object_name as well as r_folder_path were showing as empty.
I did a quick fix:

SELECT doc_s.object_name,fol_r.r_folder_path
FROM dm_sysobject_s doc_s, dm_sysobject_r doc_r, dm_folder_r fol_r
WHERE doc_s.r_object_id = doc_r.r_object_id
AND doc_r.i_folder_id = fol_r.r_object_id
AND fol_r.r_folder_path is not nullstring

The r_folder_path was not showing any empty records but the case was not so with object_name. Something clicked in my mind. My mind had found a flaw in the query which was looking fine to me till now. My friend was interested in documents; not the sysobjects. I was actually giving him a lot of garbage.

And thus I got my next query:

SELECT doc_s.object_name,fol_r.r_folder_path
FROM dm_sysobject_s doc_s, dm_sysobject_r doc_r, dm_folder_r fol_r
WHERE doc_s.r_object_id = doc_r.r_object_id
AND doc_r.i_folder_id = fol_r.r_object_id
AND fol_r.r_folder_path is not nullstring
AND doc_s.r_object_type = 'dm_document'

Cool….. My friend looks to be the happiest person on earth. He got the result he was looking for. But I still want to do one more small change.

SELECT doc_s.object_name,fol_r.r_folder_path
FROM dm_sysobject_s doc_s, dm_sysobject_r doc_r, dm_folder_r fol_r
WHERE doc_s.r_object_type = 'dm_document'
AND fol_r.r_folder_path is not nullstring
AND doc_s.r_object_id = doc_r.r_object_id
AND doc_r.i_folder_id = fol_r.r_object_id

The result is same as the earlier query but somehow I look more satisfied with this query. I am not sure how good or how efficient this query is but my friend got what he wanted and I was satisfied that I was able to help him out.

The story is not over yet. I just checked the sql equivalent of this query in the dql component of webtop.

Here is the result:

SELECT all doc_s.object_name, fol_r.r_folder_path
FROM dbo.dm_sysobject_s doc_s, dbo.dm_sysobject_r doc_r, dbo.dm_folder_r fol_r
WHERE ((doc_s.r_object_type=N'dm_document')
AND fol_r.r_folder_path != ' '
AND (doc_s.r_object_id=doc_r.r_object_id)
AND (doc_r.i_folder_id=fol_r.r_object_id))

Do you know what the most interesting part is?

After doing all this crap, I posted it on my blog. I had added tags like DQL, Documentum, etc. When I clicked on the DQL link (The tag which I had added) I got Rajendra’s blog in the result. He has posted a query there.

SELECT A.r_object_id, A.object_name, B.r_folder_path
FROM dm_document A, dm_folder_r B
WHERE any A.i_folder_id = B.r_object_id

Doesn’t that look much simple? :D:D:D

Here is another query from inthewoods. It uses DQL Hint and appears to be a better option than the earlier two.

SELECT doc.r_object_id, doc.object_name, fld.r_folder_path
FROM dm_document doc, dm_folder fld
WHERE doc.i_folder_id = fld.r_object_id ENABLE(ROW_BASED)

So.. Thats the whole story. Hope you enjoyed it.

*Guess it would be a nice idea to add ‘fld.r_folder_path is not nullstring’ and ‘order by r_object_id’ to the final query.

Read Full Post »