JMeter vs UCF

Imagine that you need to perform load tests, but you have no money to buy HP LoadRunner licences, so you think that Apache JMeter is a good opensource alternative to HP LoadRunner – from my perspective this “genius” idea sounds weird, because the main advantage of HP LoadRunner is it’s analysis engine, though, my colleagues think it is possible to collect JMeter logs and process them using MS Excel, on the other hand I had never seen a proper HP LoadRunner report – performance guys always like to provide something like:

and I have no idea how to interpret such drawings 🙂

Well, we need to implement load scenarios using Apache JMeter and the main “challenge” is emulate content transfer “facilities” (did you know that UCF is acronym for “Unified Client Facilities”?). Actually it is not a challenge at all, all what you need is following:

  • if your JMeter instance is on UNIX you need to modify wdk/contentXfer/ucf.installer.config.xml on webtop side and remove dots before “ucf” in ucfHome and ucfInstallsHome elements – you need to get “$java{user.home}/Documentum/ucf” instead of “$java{user.home}/Documentum/.ucf”
  • download ucfinit.jar to JMeter host from webtop and execute
    java -cp ucfinit.jar com.documentum.ucf.client.install.TestInstall \
    http(s)://<host>:<port>/webtop /wdk/contentXfer/ucf.installer.config.xml
  • copy all files from ~/Documentum/ucf/<host>/shared/bin/<ucf version>/ directory to JMeter’s lib/ext directory
  • set CookieManager.save.cookies=true in jmeter.properties
  • create following groovy (JSR223) sampler:
    import com.documentum.ucf.client.transport.impl.ClientSession;
    import com.documentum.ucf.client.transport.requesthandlers.spi.BaseRequestHandler;
    import com.documentum.ucf.client.transport.IClientRequest;
    import com.documentum.ucf.client.transport.IResultPackage;
    import com.documentum.ucf.common.transport.IParameter;
    import com.documentum.ucf.client.transport.impl.BaseResultPackage;
    import com.documentum.ucf.common.transport.spi.BaseResponse;
    import com.documentum.ucf.client.transport.impl.RequestProcessor;
    import com.documentum.ucf.client.transport.requesthandlers.spi.RequestHandlerMismatchException;
    import org.apache.jmeter.threads.JMeterVariables;
    
    class LaunchApplicationHandler extends BaseRequestHandler {
    
      public IResultPackage process (IClientRequest request) throws RequestHandlerMismatchException {
        BaseResultPackage result = init(request);
        BaseResponse response = (BaseResponse) result.getResponse();
        return result;
      }
    	
    }
    
    class UCFHelper {
    
      static {
        RequestProcessor requestProcessor = ClientSession.s_requestProcessor;
        requestProcessor.addHandler("LaunchApplication", new LaunchApplicationHandler());
      }
    
      public static String getCookie(JMeterVariables vars) {
        String cookie = vars.get("COOKIE_JSESSIONID");
        return "JSESSIONID=" + cookie; 	
      }
    
      public static String getUrl(JMeterVariables vars) {
        return vars.get("WebtopProtocol") + "://" + vars.get("WebtopHostName") + ":" + vars.get("WebtopPort") + vars.get("WebtopContextRoot"); 	
      }
    
      public static void createUcfSession(JMeterVariables vars) {
        String cookie = getCookie(vars);
        ClientSession session = vars.getObject("UCFSESSION");
        boolean valid = session != null && session.isAlive();
        if (valid) {
          valid = cookie.equals(session.getSessionId());	
        }
        if (valid) {
          return;	
        }
        if (session != null) {
        	 session.interrupt();
        }
        session = new ClientSession(getUrl(vars), "Gair", cookie);	
        session.startSession();
        vars.putObject("UCFSESSION", session);
        vars.put("UCFKEY", session.getUID());	
      }
    	
    }
    
    UCFHelper.createUcfSession(vars);
    
    

voilĂ :

Welcome to OpenText My Support

WordPress reports that ECD experiences difficulties with DNS configuration. Old JIRA address was: http://cmajira.lss.emc.com:8443, now it is http://10.8.93.60:8443 🙂

Alvaro de Andres' Blog

On August 25, 2017 at 8:00 P.M. EST, the Dell EMC Enterprise Content Division, including
Documentum, Application Xtender, Captiva, Kazeon, Document Sciences and LEAP will officially be integrated into OpenText Customer Support systems. While the customer service quality you’ve come to expect won’t change, the way you access support resources will.

On August 25, 2017 at 8:00 P.M. EST, OpenText’s online support portal known as My Support will become the primary system that you use to submit, update and monitor the progress of your organization’s support requests for former ECD technology products such as Application Xtender, Captiva, Documentum, Kazeon, Document Sciences and LEAP. In addition, you will be able to access support resources such as forums, documentation, knowledge base articles, account information and much more!
To help make the transition easier, we have migrated your existing tickets to My Support. Any new tickets you create with the My Support wizard…

View original post 5 more words

Weird DQL grammar. Part III

Today I noticed another odd behaviour:

API> ?,c,select count(*) from dm_sysobject 
  where a_is_template=FALSE enable(GENERATE_SQL_ONLY)
generate_sql
-------------------------------------------------
select all count(*) from dm_sysobject_sp  dm_sysobject 
  where ((dm_sysobject.a_is_template=0)) 
  and (dm_sysobject.i_has_folder = 1 and dm_sysobject.i_is_deleted = 0) 
(1 row affected)

API> ?,c,select count(*) from dm_sysobject 
  where a_is_template=0 enable(GENERATE_SQL_ONLY)
generate_sql
-------------------------------------------------
select all count(*) from dm_sysobject_sp  dm_sysobject 
  where ((dm_sysobject.a_is_template=0)) 
  and (dm_sysobject.i_has_folder = 1 and dm_sysobject.i_is_deleted = 0) 
(1 row affected)

BUT:

API> ?,c,select count(*) from dm_dbo.dm_sysobject_s 
  where a_is_template=FALSE enable(GENERATE_SQL_ONLY)
generate_sql
-------------------------------------------------
select all count(*) from docbase.dm_sysobject_s 
  where ((a_is_template=0 OR a_is_template IS NULL)) 
(1 row affected)

API> ?,c,select count(*) from dm_dbo.dm_sysobject_s 
  where a_is_template=0 enable(GENERATE_SQL_ONLY)
generate_sql
-------------------------------------------------
select all count(*) from docbase.dm_sysobject_s 
  where ((a_is_template=0 OR a_is_template IS NULL)) 
(1 row affected)

i.e. Content Server thinks that it is smart enough and in case of registered tables generates wrong SQL, there are two options to “override” such behaviour:

  • write odd DQL, like:
    API> ?,c,select count(*) from dm_dbo.dm_sysobject_s 
      where (a_is_template=FALSE and a_is_template IS NOT NULL) enable(GENERATE_SQL_ONLY)
    generate_sql                                                                                                                             
    -------------------------------------------------
    select all count(*) from bee_ssc_dev.dm_sysobject_s 
      where (((a_is_template=0 OR a_is_template IS NULL) and a_is_template is not null)) 
    (1 row affected)
    
  • write tricky DQL:
    API> ?,c,select count(*) from dm_dbo.dm_sysobject_s 
      where a_is_template IN (FALSE) enable(GENERATE_SQL_ONLY)
    generate_sql                                                                     
    -------------------------------------------------
    select all count(*) from bee_ssc_dev.dm_sysobject_s 
      where (a_is_template in (0)) 
    (1 row affected)