Tuesday, November 11, 2014

Alfresco CXF SOAP and REST Web Services

This tutorial shows you how to develop SOAP and REST CXF Web Services in Alfresco.

1. CXF to get at /services/ context File : web.xml

  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

2. CXF SOAP Service – Alfresco

  @WebService(targetNamespace = "http://soap.sample.alfresco.org", name = "AlfrescoSearchService")
   public interface AlfrescoSearchService {
    @WebMethod
    public SearchResponse searchAlfrescoRepository(@WebParam(name = "searchString") String searchString) throws java.rmi.RemoteException;
   }

*Note: Configuration file is present in Source Code and Binaries.

3. Access CXF SOAP Service – Alfresco From Chrome Client
http://localhost:8080/alfresco/services/AlfrescoSearchService?wsdl

Request Object

  <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
     <searchAlfrescoRepository xmlns="http://soap.sample.alfresco.org">
      <searchString xmlns="">Alfresco</searchString>
     </searchAlfrescoRepository>
   </Body>
  </Envelope>



Output/Response

  <soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:body>
    <ns2:searchalfrescorepositoryresponse xmlns:ns2="http://soap.sample.alfresco.org">
     <return>
      <jsonresult>{"JSONKey":[{"created":"Fri May 03 17:41:15 IST 2013","nodename":"alfresco docs.js.sample","modified":"Fri May 03 17:41:15 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_textplain_alfresco.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_texthtml_alfresco.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_textplain_alfresco_it.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_it.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_textplain_alfresco_de.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_texthtml_alfresco_de.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_textplain_alfresco_es.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_es.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_textplain_alfresco_fr.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_fr.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_textplain_alfresco_ja.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_ja.ftl","modified":"Fri May 03 17:41:19 IST 2013"}]}
      </jsonresult>
     </return>
    </ns2:searchalfrescorepositoryresponse>
   </soap:body>
  </soap:envelope>

4. CXF REST Service – Alfresco
   You will need to add “javax.ws.rs-api-2.0-m02.jar” and WEB-INF lib of your alfresco deployed folder.

  @WebService(serviceName = "AlfrescoRestSearchService", targetNamespace = "http://soap.sample.alfresco.org")
   public class AlfrescoRestSearchServiceImpl {
.................
    @GET
    @Path("/query")
    public Response searchAlfrescoRepository(@QueryParam("searchString") String searchString){
     SearchResponse responseObject = searchObject.searchRepository(searchString);
     return Response.ok(responseObject).build();
    }

   }

*Note: Configuration file is present in Source Code and Binaries.

5. Access CXF REST Service
  Request
http://localhost:8080/alfresco/services/AlfrescoRestSearchService/query?searchString=Alfresco

  Output/Response

  <SearchResponse>
    <jsonResult>
     {"JSONKey":[{"created":"Fri May 03 17:41:15 IST 2013","nodename":"alfresco docs.js.sample","modified":"Fri May 03 17:41:15 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_textplain_alfresco.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_texthtml_alfresco.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_textplain_alfresco_it.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_it.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_textplain_alfresco_de.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_texthtml_alfresco_de.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:18 IST 2013","nodename":"emailbody_textplain_alfresco_es.ftl","modified":"Fri May 03 17:41:18 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_es.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_textplain_alfresco_fr.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_fr.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_textplain_alfresco_ja.ftl","modified":"Fri May 03 17:41:19 IST 2013"},{"created":"Fri May 03 17:41:19 IST 2013","nodename":"emailbody_texthtml_alfresco_ja.ftl","modified":"Fri May 03 17:41:19 IST 2013"}]}
    </jsonResult>
  </SearchResponse>


Download Binary                Download Source Code


Monday, September 22, 2014

Alfresco Custom SearchService Junit TestCase


Many a times I was struggling when trying to run test cases those comes bundled with Alfresco. Got very less help on forums to setup environment for it and create Custom Unit test cases.

Attached Test Case runs with Alfresco version 3.3.5 and 4.0.2

If You are running this Test Case in eclipse, please add external class folder (given below ) into libraries section.
Alfresco_Home/tomcat/shared/classes and
Alfresco_Home/tomcat/webapps/alfresco/WEB-INF/classes

There are three different approaches I have used to demonstrate multiple ways to implement search in your application.


package com.search;

import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;

public class CustomSearchServiceTest{
private final static Logger logger = Logger.getLogger(CustomSearchServiceTest.class);
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private AuthenticationComponent authenticationComponent;
private SearchService pubSearchService;
private TransactionService transactionService;

@Before
public void setUp() throws Exception {
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
pubSearchService = (SearchService) ctx.getBean("SearchService");
transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
}

@After
public void tearDown() throws Exception {
logger.debug("tearDown");
}

@Test
public void testSearchParametersApproach() {
logger.debug("testApproachFirst");
String luceneQuery = "( TYPE:\"content\" AND (@cm\\:name:\"*Alfresco*\"))";
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(luceneQuery);
sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
authenticationComponent.setSystemUserAsCurrentUser();
ResultSet results = pubSearchService.query(sp);
logger.debug("results :::: " + results);
try {
if (results != null && results.length() > 0) {
logger.debug("nodeRef results 0 ::::" + results.getNodeRef(0));
}
} finally {
if (results != null) {
results.close();
}
}

}

@Test
public void testRunAsWorkApproach() {
logger.debug("testApproachSecond");
RunAsWork indexRunAs = new RunAsWork() {
public NodeRef doWork() {
NodeRef nodeRef = null;
try {
String luceneQuery = "( TYPE:\"content\" AND (@cm\\:name:\"*Alfresco*\"))";
ResultSet resultSet = pubSearchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, luceneQuery);
if (resultSet != null && resultSet.length() > 0) {
nodeRef = resultSet.getNodeRef(0);
}
if (resultSet != null) {
resultSet.close();
}
logger.debug("nodeRef results 0 ::::" + nodeRef);
} catch (Exception e) {
e.printStackTrace();

}
return nodeRef;
}
};
NodeRef results = AuthenticationUtil.runAs(indexRunAs, AuthenticationUtil.getAdminUserName());
}

@Test
public void testRetryingTransactionHelperApproach() {
logger.debug("testApproachThird");
authenticationComponent.setSystemUserAsCurrentUser();
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
RetryingTransactionCallback callback = new RetryingTransactionCallback() {
public NodeRef execute() throws Throwable {
NodeRef nodeRef = null;
String luceneQuery = "( TYPE:\"content\" AND (@cm\\:name:\"*Alfresco*\"))";
ResultSet resultSet = pubSearchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, luceneQuery);
if (resultSet != null && resultSet.length() > 0) {
nodeRef = resultSet.getNodeRef(0);
}
if (resultSet != null) {
resultSet.close();
}
return nodeRef;
}
};
NodeRef results = txnHelper.doInTransaction(callback, false, true);
logger.debug("nodeRef results ::::" + results);
}

}




Wednesday, January 2, 2013

Monitoring Alfresco through JMX

Back in some days we were facing thread locking issue on Alfresco. Got a good chance to enable JMX and see what is happening inside.

How to enable JMX extension with Tomcat (OS Solaris)?
1.Set the property -Dcom.sun.management.jmxremote in alfresco.sh file
JAVA_OPTS=" -server -d64 -Xms10g -Xmx55g -XX:MaxNewSize=10g -XX:MaxPermSize=30g -Dcom.sun.management.jmxremote “ and export JAVA_OPTS
2.Check in file \classes\alfresco\core-services-context.xml bean section “RMIRegistryFactoryBean” should not be commented.
3.For Security purpose change default passwords in below files,
/alfresco/alfresco-jmxrmi.access
/alfresco/alfresco-jmxrmi.password

How to connect JMX client to Remote Alfresco (OS Windows)?
1.Go to your installed Java directory and execute jconsole.exe
D:\cci\javatools\Java\jdk1.6.0_31\bin>jconsole.exe
2.Once jconsole is launched select “Remote Process” radio box and add URL to connect service:jmx:rmi:///jndi/rmi://:50500/alfresco/jmxrmi
3.Input username and password if you have changed. Default username/password is controlRole/change_asap





Once you are connected to remote process you can see below tabs
1.Overview- which shows Heap Memory Usage, Thread, Class and CPU Usages,
2.Memory- Detailed view of Heap Memory and Non Heap Memory Usage,
3.Thread – Detailed of individual threads
4.Classes- Number of Class loaded
5.VM summary- Detailed view of VM summary
6.MBeans- All Mbeans which are exposed either readonly or configurable.

How to user topthread.jar with JConsole?
topthread.jar will allow you to see usage history of threads, CPU usage and state of thread; you can download topthread.jar from here…
1.Go to your installed Java directory and execute jconsole.exe
jconsole.exe -pluginpath D:\cci\javatools\Java\jdk1.6.0_31\lib\topthreads.jar

2.You will be able to see extra tab “Top thread” once jconsole is connected with server.


Top Thread Analysis

Sometimes system becomes unresponsive if any thread got stuck of having more CPU usage even if application seems not to be busy. We can locate such a thread from topthreads and can kill it to get system responsive. We can adjust the refresh interval and max displayed threads to limit our analysis data instead of having much frequent refresh and hundreds of thread being displayed on one small screen.


Monday, April 12, 2010

Alfresco Search Customization

As per Alfresco documentation default search uses a Boolean "Implied AND" as like Google, Yahoo or any major search engine works. But the behavior of alfresco is seems to be using Boolean “Implied OR”.
But Customization of such kind of search is made easy by Alfresco when it comes to customize Alfresco Web Client.
Let’s go by example.
We have few resume stored as word document in our repository if we do search on Alfresco repository using keywords (java alfresco) it gives all the documents which has meta data(or Full text search) either as Java or as alfresco. But we are intended to search all those documents which have Java and alfresco both skill sets. It is the situation where alfresco default search is based on “Implied OR”.
We can configure this on Alfresco web-client customization if we are using SearchContext . We need to add the configuration in web-client-config-custom.xml as below

<alfresco-config>
   <config>
      <client>
        <!-- set this value to true to enable AND text terms for simple/advanced search by default -->
        <search-and-terms>true</search-and-terms>
      </client>
   </config>
</alfresco-config>

If you are using Search Service (Search using API) then you can set SearchParameter default operator as “implied AND” as below

SearchParameters sp = new SearchParameters();
sp.addStore(Repository.getStoreRef());
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.setDefaultOperator(SearchParameters.AND);
ResultSet nodeRefs = searchService.query(sp);

With this kind of customization we are sure that we can use exact search as like Google in our Alfresco repository.

Monday, March 29, 2010

Custom Content Transformer

Alfresco has content transformer for most of mime type we are using day to day. But We wanted to have Custom Content Transformer,to show preview of .xfdl file.

.xfdl is extension for electronic form provided by Lotus Forms. This blog is more of creating a Custom Content Transformer for xfdl mime type.

1.How to register new Content Type i.e. “.xfdl”
Create new file “mimetype-custom-extensions.xml” at level “alfresco/mimetype” parallel level to “alfresco/extension” it should not go under “alfresco/extension” e.g. say mimetype-custom-extensions.xml
In this file we configure alfresco-config for area mimetype-map. Define correct mimetype for your extension here.


2.How to register new Custom Content Transformer
Create new file custom-services-context.xml under “alfresco/extension” folder e.g. custom-services-context.xml

In this file we need to define bean for "mimetypeConfigService" and new bean "transformer.xfdlToText" for Transformer "XFDLContentTransformer".


3. Create Custom Content Transformer “XFDLContentTransformer.java”
This is class where Transformation will take place for you extension mimetype. This class will extends the functionality from "AbstractContentTransformer" . This class uses a "transformText" method to transform it. You have different for you different extension and mimetype.


You can download the code from here ...
http://docs.google.com/leaf?id=0B2GTDzbcX3UsYjliNTAxMjYtNTkwMi00YmI4LTkyODgtZTA3OGQwNjQyN2Qw&hl=en

Wednesday, January 27, 2010

Alfresco FirstFoundationClient (How to setup and Run)

With this blog you will be able to setup and Run FirstFoundationClient sample of Alfresco.

1. Import FirstFoundationClient Project in eclipse (Assuming you are using eclipse).
2. Specify repository properties with “source/alfresco/extension/custom-repository.properties”.


#
# Sample custom content and index data location
#

dir.root=D:/javatools/alfrescorepo/alf_data
dir.indexes=D:/javatools/alfrescorepo/alf_data/lucene-indexes

#
# Sample database connection properties
#
db.name=alfrescorepodb
db.username=workalfresco
db.password=workalfresco
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/alfrescorepodb


3. Create New file “custom-hibernate-dialect.properties” under “source/alfresco/extension”.
#
# Sample Hibernate configuration for changing Database dialect
# For a full list: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#configuration-optional-dialects
#


#
# PostgreSQL dialect
#
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.query.substitutions=true TRUE, false FALSE


4. Create new bean definition “hibernateConfigProperties” in “source/alfresco/extension/custom-repository-context.xml”.

<bean id="hibernateConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:alfresco/domain/hibernate-cfg.properties</value>

<!-- Override hibernate dialect -->
<value>classpath:alfresco/extension/custom-hibernate-dialect.properties</value>
</list>
</property>
</bean>


5. Run FirstFoundationClient.java with main method.

Note:
1. If you are using PostgreSQL or any other database please provide driver classpath or add additional jar to your project.
2. If your alfresco tomcat server is already Running Please try to change avm.jmxrmi.port from 50500 to 50502 and avm.remote.port from 1313 to 1315 in “/source/alfresco/extension/custom-alfresco-shared.properties”.

Tuesday, December 1, 2009

Dynamic deployment of Alfresco Custom Workflow

This feature is available from Alfreso 3.0 and above.

Alfresco 3 has given the facility of Dynamic Deployment for
1.New content/Workflow model.
2.Message Resource Bundle.
3.Alfresco Explorer configuration (Web-client-config.xml).
4.Workflow Process Definition.

Please download this pdf file for working example.

http://docs.google.com/fileview?id=0B2GTDzbcX3UsMWE2NTRmNGYtNDhhNC00NTIyLTllZjYtOTNmMmZlMjc2OWNl&hl=en