1

I have got demo example CeConnection.java class, available from IBM site (http://www-01.ibm.com/support/docview.wss?uid=swg24028788) the listing of this class you can find at the top of message.

So, my webapp communicating with Content Engine using single user (yes yes, single 'ce_user' with 'passw123'). And could you kindly explain good practice, good approach to use this CeConnection class for each user's session in my Vaadin webapp (vaadin's entry point - AppMain.java class can has CeConnection field).

Which of the following approach is ok?

1. When the webapp starts I establish connection: 
  void init() {  // this is vaadins entry point

  ceConnection  = new CeConnection();

  ceConnection.establishConnection(...);

  }



OR

2. Create new CeConnection for every request to Content Engine. like:

    Document getDoc(String id) {
         CeConnection ceConnection = new CeConnection(...) 
         try {
         ceConnection.establish(); // (contains UserContext.pushSubject)

         ...get data from CE....
         } finally {
         ceConenction.logofMethod();  (contains UserContext.popSubject)
         }
        }

Thank you!

/**
    IBM grants you a nonexclusive copyright license to use all programming code 
    examples from which you can generate similar function tailored to your own 
    specific needs.

    All sample code is provided by IBM for illustrative purposes only.
    These examples have not been thoroughly tested under all conditions.  IBM, 
    therefore cannot guarantee or imply reliability, serviceability, or function of 
    these programs.

    All Programs or code component contained herein are provided to you �AS IS � 
    without any warranties of any kind.
    The implied warranties of non-infringement, merchantability and fitness for a 
    particular purpose are expressly disclaimed.

    � Copyright IBM Corporation 2007, ALL RIGHTS RESERVED.
 */

package cesample;

import java.util.Iterator;
import java.util.Vector;
import javax.security.auth.Subject;
import com.filenet.api.collection.ObjectStoreSet;
import com.filenet.api.core.Connection;
import com.filenet.api.core.Domain;
import com.filenet.api.core.Factory;
import com.filenet.api.core.ObjectStore;
import com.filenet.api.util.UserContext;

/**
 * This object represents the connection with
 * the Content Engine. Once connection is established
 * it intializes Domain and ObjectStoreSet with
 * available Domain and ObjectStoreSet.
 * 
 */
public class CEConnection 
{
    private Connection con;
    private Domain dom;
    private String domainName;
    private ObjectStoreSet ost;
    private Vector osnames;
    private boolean isConnected;
    private UserContext uc;

    /*
     * constructor
     */
    public CEConnection()
    {
        con = null;
        uc = UserContext.get();
        dom = null;
        domainName = null;
        ost = null;
        osnames = new Vector();
        isConnected = false;
    }

    /*
     * Establishes connection with Content Engine using
     * supplied username, password, JAAS stanza and CE Uri.
     */
    public void establishConnection(String userName, String password, String stanza, String uri)
    {
        con = Factory.Connection.getConnection(uri);
        Subject sub = UserContext.createSubject(con,userName,password,stanza);
        uc.pushSubject(sub);
        dom = fetchDomain();
        domainName = dom.get_Name();
        ost = getOSSet();
        isConnected = true;
    }

    /*
     * Returns Domain object.
     */
    public Domain fetchDomain()
    {
        dom = Factory.Domain.fetchInstance(con, null, null);
        return dom;
    }

    /*
     * Returns ObjectStoreSet from Domain
     */
    public ObjectStoreSet getOSSet()
    {
        ost = dom.get_ObjectStores();
        return ost;
    }

    /*
     * Returns vector containing ObjectStore
     * names from object stores available in
     * ObjectStoreSet.
     */
    public Vector getOSNames()
    {
        if(osnames.isEmpty())
        {
            Iterator it = ost.iterator();
            while(it.hasNext())
            {
                ObjectStore os = (ObjectStore) it.next();
                osnames.add(os.get_DisplayName());
            }
        }
        return osnames;
    }

    /*
     * Checks whether connection has established
     * with the Content Engine or not.
     */
    public boolean isConnected() 
    {
        return isConnected;
    }

    /*
     * Returns ObjectStore object for supplied
     * object store name.
     */
    public ObjectStore fetchOS(String name)
    {
        ObjectStore os = Factory.ObjectStore.fetchInstance(dom, name, null);
        return os;
    }

    /*
     * Returns the domain name.
     */
    public String getDomainName()
    {
        return domainName;
    }
}

EDIT: ADDED

I am wondering, what happens if two client will call servlet method almost simultaneously, and one client will call PopSubject first? Is com.filenet.api.util.UserContext class thread-safe?

servlet method:

public String getDocumentNumber(String id) {

 UserContext.get().pushSubject(mySubject);
 try {
   ....
   ....
   ....
   ....
 } finally {
   UserContext.get().popSubject();
 }

}

//com.filenet.api.util.UserContext class

public static UserContext get() {
        UserContext cntx = (UserContext)tl.get();
        if(cntx == null) {
            cntx = new UserContext();
            tl.set(cntx);
        }

        return cntx;
    }


public synchronized void pushSubject(Subject sub) {

        if(sub == null) {
            throw new EngineRuntimeException(ExceptionCode.E_NULL_OR_INVALID_PARAM_VALUE, "Subject");
        } else {
            this.subjects.add(sub);
        }
}


public synchronized Subject popSubject() {

        return this.subjects.isEmpty()?null:(Subject)this.subjects.remove(this.subjects.size() - 1);
}
ᄂ ᄀ
  • 5,669
  • 6
  • 43
  • 57

1 Answers1

1

I would suggest connecting to CE when required not during application loading. No harm in connecting while application starts as CE objectstore is just a POJO but I would prefer when I need.

Also from your code, I could see that you have used ceConenction.logofMethod();a word of caution is that you need to call this method when you are done with all your CE operations otherwise you will get errors. Let's take an example

  1. Users logs in
  2. User want to let's say add a document so you establish connection
  3. Your code adds the document
  4. then your finally block executes and ceConenction.logofMethod();
  5. Immediately after this, if you want the user to perform any CE operations like delete or update, you will get an exception. So you need to get objectstore again.

Hope this helps.

bajji
  • 1,271
  • 3
  • 15
  • 37
  • Thanks for the answer. I've edited my question, could you review. "I am wondering, what happens if two client will call servlet method almost simultaneously, and one client will call PopSubject first? Is com.filenet.api.util.UserContext class thread-safe?" – Azamat Almukhametov Oct 06 '17 at 12:27
  • This link should clear your doubt's https://www.ibm.com/support/knowledgecenter/en/SSNW2F_5.2.1/com.ibm.p8.ce.dev.java.doc/com/filenet/api/util/UserContext.html – bajji Oct 10 '17 at 13:27