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);
}

}