Weird Search bug with Lucene

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
rsfeir
Member II

Weird Search bug with Lucene

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
andy
Active Member

Re: Weird Search bug with Lucene

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
Member II

Re: Weird Search bug with Lucene

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
Member II

Re: Weird Search bug with Lucene

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
Member II

Re: Weird Search bug with Lucene

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