cancel
Showing results for 
Search instead for 
Did you mean: 

Weird Search bug with Lucene

rsfeir
Champ in-the-making
Champ in-the-making
Hello again.

I'm trying to implement checks on workflow with web services so that in the following scenario, I get back the approved content only.

So say I have 3 spaces:

1- Triage
2- Rejected
3- Approved.

I have a rule which says that when an item is added it needs to be approved or rejected.  If it's approved it goes in #3 and if rejected it goes in #2, when content is added it's added to #1.

Now that part works OK.

So I added a document with Title of Info to triage and I approved the document.  Then I added another document with title Info and rejected it.

With my service alive and kicking, I run a query which looks for any document named Info.  Don't care if it's rejected or accepted yet.

The problem is that I get a NPE because the resultset is null, in otherwords it can't find the document called Info.  It can find other documents which are in the Triage space.  If I add Info to triage, nothing comes back either and I get the NPE again.

I believe the problem might be Lucene related, where lucene is not indexing things right.  I am looking for all documents in the SpacesStore location.

Any clues why I would be getting vast differences in behavior when searching over web services?

Thanks
R
4 REPLIES 4

andy
Champ on-the-rise
Champ on-the-rise
Hi

Can you send the query, the code (if you have added any)  and the error?

I am not sure how the resujlt set is null.

Regards

Andy

rsfeir
Champ in-the-making
Champ in-the-making
Since I'm not sure where to post code to I'll do it here, there is nothing proprietary about it, most of it is derived from your samples:

package gov.nih.niaid.eric;

import org.alfresco.www.ws.model.content.Query;
import org.alfresco.www.ws.model.content.QueryLanguageEnum;
import org.alfresco.www.ws.model.content.Reference;
import org.alfresco.www.ws.model.content.ResultSet;
import org.alfresco.www.ws.model.content.ResultSetRow;
import org.alfresco.www.ws.model.content.Store;
import org.alfresco.www.ws.model.content.StoreEnum;
import org.alfresco.www.ws.service.authentication.AuthenticationResult;
import org.alfresco.www.ws.service.authentication.AuthenticationServiceLocator;
import org.alfresco.www.ws.service.authentication.AuthenticationServiceSoapBindingStub;
import org.alfresco.www.ws.service.content.ContentServiceLocator;
import org.alfresco.www.ws.service.content.ContentServiceSoapBindingStub;
import org.alfresco.www.ws.service.content.ReadResult;
import org.alfresco.www.ws.service.repository.QueryResult;
import org.alfresco.www.ws.service.repository.RepositoryFault;
import org.alfresco.www.ws.service.repository.RepositoryServiceLocator;
import org.alfresco.www.ws.service.repository.RepositoryServiceSoapBindingStub;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.configuration.FileProvider;
import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.rpc.ServiceException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.rmi.RemoteException;

/**
* Web service sample 1.
* <p/>
* Connect to the reposity and get a list of all the stores available in the repository.
*
* @author Roy Wetherall
*/
public class AlfrescoRepositoryHelper implements CallbackHandler {
    /**
     * Admin user name and password used to connect to the repository we can change this to user with less privs
     */
    public static final String USERNAME = "admin";
    public static final String PASSWORD = "admin";
    private static RepositoryServiceSoapBindingStub repositoryService = null;
    public static String currentTicket;

    /**
     * WS security information, don't change this, it's need to for proper callback in the headers.
     */
    public static final String WS_SECURITY_INFO =
            "<deployment xmlns='http://xml.apache.org/axis/wsdd/' xmlns:java='http://xml.apache.org/axis/wsdd/providers/java'>" +
                    "   <transport name='http' pivot='javaSmiley Surprisedrg.apache.axis.transport.http.HTTPSender'/>" +
                    "   <globalConfiguration >" +
                    "      <requestFlow >" +
                    "       <handler type='javaSmiley Surprisedrg.apache.ws.axis.security.WSDoAllSender' >" +
                    "               <parameter name='action' value='UsernameToken'/>" +
                    "               <parameter name='user' value='ticket'/>" +
                    "               <parameter name='passwordCallbackClass' value='gov.nih.niaid.eric.AlfrescoRepositoryHelper'/>" +
                    "               <parameter name='passwordType' value='PasswordText'/>" +
                    "           </handler>" +
                    "       </requestFlow >" +
                    "   </globalConfiguration>" +
                    "</deployment>";


    public static String getContentLocation(final String contentToFind, final String storeLocation) throws IOException, ServiceException, NullPointerException {
        //Gets an authentication to the repo and gets a ticket to work with.
        final AuthenticationServiceSoapBindingStub authenticationService = AlfrescoRepositoryHelper.getTicket();
        //Executes the search which returns the file in question.
        final Reference myNode = findContent(contentToFind, storeLocation);
        // Get the content service
        final ContentServiceSoapBindingStub contentService = getContentWebService();
        // Read the newly added content from the respository
        final ReadResult readResult = contentService.read(myNode);
        final String contentLocation = getContentURL(AlfrescoRepositoryHelper.currentTicket, readResult.getUrl());
        // End the session
        assert authenticationService != null;
        authenticationService.endSession();
        return contentLocation;
    }

    private static AuthenticationServiceSoapBindingStub getTicket() throws ServiceException, RemoteException {
        final AuthenticationServiceSoapBindingStub authenticationService = (AuthenticationServiceSoapBindingStub) new AuthenticationServiceLocator().getAuthenticationService();
        // Get a reference to the respository web service
        repositoryService = getRepositoryWebService();
        // Start the session
        final AuthenticationResult result = authenticationService.startSession(AlfrescoRepositoryHelper.USERNAME, AlfrescoRepositoryHelper.PASSWORD);
        AlfrescoRepositoryHelper.currentTicket = result.getTicket();
        return authenticationService;
    }

    /**
     * Executes a query looking for theContent in the storeLocation and returns the first item found.
     *
     * @return returns a content reference item which contains the information about the page we're trying to display
     * @throws java.rmi.RemoteException Remove exception
     * @throws org.alfresco.www.ws.service.repository.RepositoryFault
     *                                  Repository fault
     * @throws NullPointerException when a content is not found.  The portlet is responsible for dealing with that and displaying the appropriate message.
     */
    private static Reference findContent(final String theContent, final String storeLocation) throws RemoteException, RepositoryFault, NullPointerException {
        // Create a store object referencing the main spaced store
        final Store store = new Store(StoreEnum.workspace, storeLocation);
        // Create a query object, look for the item specified in the theContent variable
        final Query query = new Query(QueryLanguageEnum.lucene, theContent);
        // Execute the query
        final QueryResult queryResult = repositoryService.query(store, query, false);
        // Display the results
        final ResultSet resultSet = queryResult.getResultSet();
        final ResultSetRow row = resultSet.getRows(0);
        Reference reference = null;
        if (row == null) {
            return new Reference();
        } else {
            // Get the id of the first result
            final String firstResultId = row.getNode().getId();
            reference = new Reference(store, firstResultId, null);
        }
        return reference;
    }


    /**
     * This method gets the content from the download servlet for a given URL and returns it as a string.
     *
     * @param ticket the current ticket
     * @param strUrl the content URL
     * @return the content as a string
     * @throws IOException
     */
    private static String getContentURL(final String ticket, String strUrl) throws IOException {
        //build the URL with ticket
        strUrl += "?ticket=" + ticket;
        // Connect to donwload servlet
        final StringBuilder readContent = new StringBuilder();
        final URL url = new URL(strUrl);
        final URLConnection conn = url.openConnection();
        final InputStream is = conn.getInputStream();
        int read = is.read();
        while (read != -1)
        {
           readContent.append((char)read);
           read = is.read();
        }
        return readContent.toString();
    }


    /**
     * Get the respository web service.
     *
     * @return the respository web service
     * @throws ServiceException Service Exception
     */
    private static RepositoryServiceSoapBindingStub getRepositoryWebService() throws ServiceException {
        // Create the respository service, adding the WS security header information
        final EngineConfiguration config = new FileProvider(new ByteArrayInputStream(AlfrescoRepositoryHelper.WS_SECURITY_INFO.getBytes()));
        final RepositoryServiceLocator repositoryServiceLocator = new RepositoryServiceLocator(config);
        final RepositoryServiceSoapBindingStub repositoryService = (RepositoryServiceSoapBindingStub) repositoryServiceLocator.getRepositoryService();
        return repositoryService;
    }

    /**
     * The implementation of the passwrod call back used by the WS Security
     * This is an implementation provided by Alfresco
     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
     */
    public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof WSPasswordCallback) {
                final WSPasswordCallback pc = (WSPasswordCallback) callback;
                pc.setPassword(currentTicket);
            } else {
                throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
            }
        }
    }

    /**
     * Get the content web service
     *
     * @return content web service
     * @throws ServiceException
     */
    private static ContentServiceSoapBindingStub getContentWebService() throws ServiceException {
        // Create the content service, adding the WS security header information
        final EngineConfiguration config = new FileProvider(new ByteArrayInputStream(AlfrescoRepositoryHelper.WS_SECURITY_INFO.getBytes()));
        final ContentServiceLocator contentServiceLocator = new ContentServiceLocator(config);
        return (ContentServiceSoapBindingStub) contentServiceLocator.getContentService();
    }
}

rsfeir
Champ in-the-making
Champ in-the-making
The exception:

10:43:15,500 ERROR [CoreServlet] Error
java.lang.NullPointerException
   at org.alfresco.www.ws.model.content.ResultSet.getRows(ResultSet.java:50)
   at gov.nih.niaid.eric.AlfrescoRepositoryHelper.findContent(AlfrescoRepositoryHelper.java:114)
   at gov.nih.niaid.eric.AlfrescoRepositoryHelper.getContentLocation(AlfrescoRepositoryHelper.java:74)
   at gov.nih.niaid.eric.WSViewPortlet.doView(WSViewPortlet.java:24)
   at javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:154)
   at javax.portlet.GenericPortlet.render(GenericPortlet.java:394)
   at org.jboss.portal.portlet.invocation.DispatcherInterceptor.invokeRequest(DispatcherInterceptor.java:163)
   at org.jboss.portal.portlet.invocation.DispatcherInterceptor.invoke(DispatcherInterceptor.java:195)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.portlet.invocation.PreferencesInterceptor.invoke(PreferencesInterceptor.java:93)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.server.invocation.component.ContextDispatcherInterceptor$InvokeNextCommand.execute(ContextDispatcherInterceptor.java:94)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.jboss.portal.server.servlet.CommandServlet.doGet(CommandServlet.java:49)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
   at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:539)
   at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
   at org.jboss.portal.server.invocation.component.ContextDispatcherInterceptor.invoke(ContextDispatcherInterceptor.java:58)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.core.invocation.AccessControlInterceptor.invoke(AccessControlInterceptor.java:125)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.server.invocation.component.CacheInterceptor.invoke(CacheInterceptor.java:74)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:238)
   at org.jboss.portal.server.Component.invoke(Component.java:173)
   at org.jboss.portal.server.invocation.portal.MainDispatcherInterceptor.invoke(MainDispatcherInterceptor.java:93)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.core.invocation.StrategyInterceptor.invoke(StrategyInterceptor.java:184)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.core.invocation.ViewInterceptor.invoke(ViewInterceptor.java:118)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.server.invocation.portal.TargetInterceptor.invoke(TargetInterceptor.java:153)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.core.invocation.ContentTypeInterceptor.invoke(ContentTypeInterceptor.java:117)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.core.invocation.UserContextInterceptor.invoke(UserContextInterceptor.java:92)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:213)
   at org.jboss.portal.server.impl.invocation.InvocationImpl.invokeNext(InvocationImpl.java:238)
   at org.jboss.portal.server.PortalServer.invoke(PortalServer.java:186)
   at org.jboss.portal.server.servlet.AbstractMainServlet.invoke(AbstractMainServlet.java:80)
   at org.jboss.portal.server.servlet.AbstractMainServlet.doGet(AbstractMainServlet.java:73)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
   at org.jboss.portal.core.servlet.TransactionFilter.doFilter(TransactionFilter.java:79)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
   at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
   at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
   at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:153)
   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:407)
   at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
   at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
   at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
   at java.lang.Thread.run(Thread.java:595)

rsfeir
Champ in-the-making
Champ in-the-making
Here's the unit test I use to test the code:

public class WSCallbackTest extends TestCase {

    public void testContentLocation() throws Exception {

        String url = AlfrescoRepositoryHelper.getContentLocation("Info", "SpacesStore");
        assertNotNull(url);
        assertTrue("We should be getting back a small protlet", url.indexOf("smallPortlet") > -1);
        try {
            AlfrescoRepositoryHelper.getContentLocation("Infoss", "SpacesStore");
        } catch (Exception e) {
            assertTrue(e.toString().indexOf("NullPointerException") > -1);
        }
    }
}