added dnet-core-services, which embeds old cnr-notifications-common, cnr-blackboard-common, cnr-resultset-service
This commit is contained in:
parent
ec964c0c47
commit
c121531bdc
|
@ -16,10 +16,14 @@ import org.dom4j.Document;
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
import org.dom4j.io.SAXReader;
|
import org.dom4j.io.SAXReader;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
// TODO investigate why it takes so long to run
|
||||||
|
// Time elapsed: 303.806 sec - in eu.dnetlib.miscutils.iterators.xml.IterableXmlParserTest
|
||||||
public class IterableXmlParserTest {
|
public class IterableXmlParserTest {
|
||||||
|
|
||||||
private Resource xmlZip = new ClassPathResource("eu/dnetlib/miscutils/iterators/xml/opendoar.zip");
|
private Resource xmlZip = new ClassPathResource("eu/dnetlib/miscutils/iterators/xml/opendoar.zip");
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>eu.dnetlib</groupId>
|
||||||
|
<artifactId>dnet-core</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>dnet-core-services</artifactId>
|
||||||
|
<groupId>eu.dnetlib</groupId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>eu.dnetlib</groupId>
|
||||||
|
<artifactId>dnet-core-components</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,61 @@
|
||||||
|
package eu.dnetlib.enabling.hcm;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.hcm.rmi.HostingContextManagerService;
|
||||||
|
import eu.dnetlib.enabling.tools.AbstractBaseService;
|
||||||
|
import eu.dnetlib.enabling.tools.blackboard.NotificationHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CNR HostingContextManagerService implementation. Will conflict with NKUA! yes this is ok.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HostingContextManagerServiceImpl extends AbstractBaseService implements HostingContextManagerService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(HostingContextManagerServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notification handler.
|
||||||
|
*/
|
||||||
|
private NotificationHandler notificationHandler; // NOPMD
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(String subscrId, String topic, String isId, String message) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("---- service got notification ----");
|
||||||
|
log.debug("subscrId: " + subscrId);
|
||||||
|
log.debug("topic " + topic);
|
||||||
|
log.debug("isId " + isId);
|
||||||
|
log.debug("msg: " + message);
|
||||||
|
log.debug("____ now processing the notification ____");
|
||||||
|
}
|
||||||
|
getNotificationHandler().notified(subscrId, topic, isId, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.tools.AbstractBaseService#start()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
log.info("staring hosting context manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotificationHandler getNotificationHandler() {
|
||||||
|
return notificationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setNotificationHandler(NotificationHandler notificationHandler) {
|
||||||
|
this.notificationHandler = notificationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package eu.dnetlib.enabling.hcm.sn;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.is.sn.rmi.ISSNException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component takes care of subscribing the MSRO service to interesting events.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface HCMSubscriber {
|
||||||
|
/**
|
||||||
|
* performs the subscription.
|
||||||
|
* @throws ISSNException could happen
|
||||||
|
*/
|
||||||
|
void subscribeAll() throws ISSNException;
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package eu.dnetlib.enabling.hcm.sn;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.xml.ws.Endpoint;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.actions.SubscriptionAction;
|
||||||
|
import eu.dnetlib.enabling.is.sn.rmi.ISSNException;
|
||||||
|
import eu.dnetlib.enabling.is.sn.rmi.ISSNService;
|
||||||
|
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
|
||||||
|
import eu.dnetlib.soap.EndpointReferenceBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component takes care of subscribing the SubscriptionAction(s) to interesting events.
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HCMSubscriberImpl implements HCMSubscriber {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(HCMSubscriberImpl.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notification endpoint (normally the msro service).
|
||||||
|
*/
|
||||||
|
private Endpoint endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* service locator.
|
||||||
|
*/
|
||||||
|
private UniqueServiceLocator serviceLocator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* injected EPR builder.
|
||||||
|
*/
|
||||||
|
@Resource(name = "jaxwsEndpointReferenceBuilder")
|
||||||
|
private EndpointReferenceBuilder<Endpoint> eprBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* subscription actions.
|
||||||
|
*/
|
||||||
|
private List<SubscriptionAction> actions;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void printList() {
|
||||||
|
log.info(getActions());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @throws ISSNException
|
||||||
|
* could happen
|
||||||
|
* @see eu.dnetlib.enabling.hcm.sn.HCMSubscriber#subscribeAll()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void subscribeAll() throws ISSNException {
|
||||||
|
|
||||||
|
final W3CEndpointReference endpointReference = eprBuilder
|
||||||
|
.getEndpointReference(getEndpoint());
|
||||||
|
|
||||||
|
if (getActions() != null) {
|
||||||
|
for (final SubscriptionAction action : getActions()) {
|
||||||
|
log.info("dynamically subscribing to "
|
||||||
|
+ action.getTopicExpression());
|
||||||
|
serviceLocator.getService(ISSNService.class, true).subscribe(endpointReference,
|
||||||
|
action.getTopicExpression(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndpoint(final Endpoint endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Endpoint getEndpoint() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEprBuilder(
|
||||||
|
final EndpointReferenceBuilder<Endpoint> eprBuilder) {
|
||||||
|
this.eprBuilder = eprBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndpointReferenceBuilder<Endpoint> getEprBuilder() {
|
||||||
|
return eprBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubscriptionAction> getActions() {
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setActions(final List<SubscriptionAction> actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniqueServiceLocator getServiceLocator() {
|
||||||
|
return serviceLocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
|
||||||
|
this.serviceLocator = serviceLocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package eu.dnetlib.enabling.hcm.sn;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import eu.dnetlib.enabling.actions.SubscriptionAction;
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class acts as a simple registry of msro subscription actions.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Subscription actions are autodetected using spring autowiring from the current application context and are available for the manager for
|
||||||
|
* handling subscriptions and delivering notification to particular code interested in those notifications.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public class HCMSubscriptionListFactory implements FactoryBean<List<SubscriptionAction>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* actions. Spring injects all the declared SubscriptionActions here.
|
||||||
|
*/
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<SubscriptionAction> actions = Lists.newArrayList();
|
||||||
|
|
||||||
|
public List<SubscriptionAction> getActions() {
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActions(final List<SubscriptionAction> actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<SubscriptionAction> getObject() {
|
||||||
|
return getActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<List> getObjectType() {
|
||||||
|
return List.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package eu.dnetlib.enabling.hnm;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.hnm.rmi.HostingNodeManagerService;
|
||||||
|
import eu.dnetlib.enabling.tools.AbstractBaseService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HNMService implementation.
|
||||||
|
*
|
||||||
|
* @author michele
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HostingNodeManagerServiceImpl extends AbstractBaseService implements HostingNodeManagerService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String echo(String s) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.observer.DelegationObserver;
|
||||||
|
import eu.dnetlib.enabling.resultset.observer.Observable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common stuff for resultset implementations bound to a ResultSetRegistry.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractObservableResultset implements ResultSet, Observable {
|
||||||
|
/**
|
||||||
|
* true if the resultset is destroyed.
|
||||||
|
*/
|
||||||
|
private boolean destroyed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if the resultset is open.
|
||||||
|
*/
|
||||||
|
private boolean open;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delegate the real job to a java.util.Observable object.
|
||||||
|
*/
|
||||||
|
private transient final java.util.Observable observable = new DelegationObservable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* weak map for removing single observers later on.
|
||||||
|
*/
|
||||||
|
private transient Map<ResultSetRegistry, DelegationObserver> observers = new WeakHashMap<ResultSetRegistry, DelegationObserver>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* java.util.Observable requires a "change" in the object to be made for the notifyObservers methods to trigger
|
||||||
|
* actually the notification. We don't think this should be part of the base Observable/Observer pattern and thus
|
||||||
|
* hide this fact. If an user of AbstractObservable wants this behavior it should implement her own change tracking
|
||||||
|
* and avoid calling notifyObservers altogether. The rationale behind this choice is that not all dirty states can
|
||||||
|
* be expressed using a stateful boolean instance variable like that implemented by java.util.Observable; some users
|
||||||
|
* may prefer/need a lazy dirty flag instead.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static class DelegationObservable extends java.util.Observable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see java.util.Observable#notifyObservers()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void notifyObservers() {
|
||||||
|
setChanged();
|
||||||
|
super.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see java.util.Observable#notifyObservers(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void notifyObservers(final Object arg) {
|
||||||
|
setChanged();
|
||||||
|
super.notifyObservers(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSet#destroy()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
if (!isDestroyed()) {
|
||||||
|
setDestroyed(true);
|
||||||
|
notifyObservers();
|
||||||
|
deleteObservers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestroyed(final boolean destroyed) {
|
||||||
|
this.destroyed = destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
return destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSet#isOpen()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSet#close()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpen(final boolean open) {
|
||||||
|
this.open = open;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addObserver(final ResultSetRegistry observer) {
|
||||||
|
final DelegationObserver delegate = new DelegationObserver(this, observer);
|
||||||
|
observers.put(observer, delegate);
|
||||||
|
observable.addObserver(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyObservers() {
|
||||||
|
observable.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyObservers(final Object arg) {
|
||||||
|
observable.notifyObservers(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countObservers() {
|
||||||
|
return observable.countObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteObserver(final java.util.Observer observer) {
|
||||||
|
observable.deleteObserver(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteObserver(ResultSetRegistry observer) {
|
||||||
|
DelegationObserver delegate = observers.get(observer);
|
||||||
|
if(delegate != null) {
|
||||||
|
observable.deleteObserver(delegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteObservers() {
|
||||||
|
observable.deleteObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resultset factories bound to a resultset service, from which it takes the resultset registry and the epr builder.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractResultSetFactory implements ResultSetFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset service.
|
||||||
|
*/
|
||||||
|
private ResultSetServiceImpl resultSetService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a resultset instance to the underlying resultset registry and returns
|
||||||
|
* and EPR to accessible through the resultset service.
|
||||||
|
*
|
||||||
|
* @param resultSet resultset instance
|
||||||
|
* @return epr to the newly created resultset
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference registerResultSet(final ResultSet resultSet) {
|
||||||
|
resultSetService.getResultsetRegistry().addResultSet(resultSet);
|
||||||
|
return resultSetService.getEprBuilder().getEndpointReference(resultSetService.getEndpoint(), resultSet.getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetServiceImpl getResultSetService() {
|
||||||
|
return resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSetService(final ResultSetServiceImpl resultSetService) {
|
||||||
|
this.resultSetService = resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
|
||||||
|
public class CachingResultSetFactory {
|
||||||
|
/**
|
||||||
|
* underlying resultset factory, which exposes local resultsets to the world.
|
||||||
|
*/
|
||||||
|
private ResultSetFactory resultSetFactory;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ServiceResolver serviceResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param items
|
||||||
|
* @param size
|
||||||
|
* the size of the iterable
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createCachingResultSet(W3CEndpointReference epr) {
|
||||||
|
return resultSetFactory.createResultSet(new CachingResultSetListener(epr, serviceResolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetFactory getResultSetFactory() {
|
||||||
|
return resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setResultSetFactory(ResultSetFactory resultSetFactory) {
|
||||||
|
this.resultSetFactory = resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceResolver getServiceResolver() {
|
||||||
|
return serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceResolver(ServiceResolver serviceResolver) {
|
||||||
|
this.serviceResolver = serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
|
||||||
|
public class CachingResultSetListener implements ResultSetListener {
|
||||||
|
private static final Log log = LogFactory.getLog(CachingResultSetListener.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
|
||||||
|
private ResultSetService service;
|
||||||
|
private String rsId;
|
||||||
|
|
||||||
|
private ArrayList<String> storage = new ArrayList<String>();
|
||||||
|
|
||||||
|
public CachingResultSetListener(W3CEndpointReference epr, ServiceResolver serviceResolver) {
|
||||||
|
this.service = serviceResolver.getService(ResultSetService.class, epr);
|
||||||
|
this.rsId = serviceResolver.getResourceIdentifier(epr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(int fromPosition, int toPosition) {
|
||||||
|
if (storage.get(fromPosition) != null)
|
||||||
|
return cached(fromPosition, toPosition);
|
||||||
|
try {
|
||||||
|
List<String> data = service.getResult(rsId, fromPosition, toPosition, "waiting");
|
||||||
|
cache(data, fromPosition, toPosition);
|
||||||
|
return data;
|
||||||
|
} catch (ResultSetException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cache(List<String> data, int fromPosition, int toPosition) {
|
||||||
|
for(String value : data)
|
||||||
|
storage.set(fromPosition++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> cached(int fromPosition, int toPosition) {
|
||||||
|
log.info("found cached page " + fromPosition + ", " + toPosition);
|
||||||
|
return storage.subList(fromPosition-1, toPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
try {
|
||||||
|
return service.getNumberOfElements(rsId);
|
||||||
|
} catch (ResultSetException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
import eu.dnetlib.miscutils.functional.IdentityFunction;
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A resultset record counter.
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CountingResultSet extends MappedResultSet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* counter.
|
||||||
|
*/
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param epr
|
||||||
|
* @param serviceResolver
|
||||||
|
*/
|
||||||
|
public CountingResultSet(final W3CEndpointReference epr, final ServiceResolver serviceResolver) {
|
||||||
|
this(epr, new IdentityFunction<String>(), serviceResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param epr
|
||||||
|
* @param mapper
|
||||||
|
* @param serviceResolver
|
||||||
|
*/
|
||||||
|
public CountingResultSet(final W3CEndpointReference epr, final UnaryFunction<String, String> mapper, final ServiceResolver serviceResolver) {
|
||||||
|
super(epr, mapper, serviceResolver);
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method sets the counter to the higher allowed value of toPosition.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(int fromPosition, int toPosition) {
|
||||||
|
|
||||||
|
if (toPosition > count)
|
||||||
|
count = toPosition;
|
||||||
|
if (toPosition > super.getSize())
|
||||||
|
count = super.getSize();
|
||||||
|
|
||||||
|
return super.getResult(fromPosition, toPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new resultset which takes each record of the input resultset and counts them.
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CountingResultSetFactory extends MappedResultSetFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new resultset which takes each record of the input resultset and counts them.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* source resultset epr
|
||||||
|
* @param mapper
|
||||||
|
* mapper function
|
||||||
|
* @return mapped resultset epr
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createCountingResultSet(final W3CEndpointReference source) {
|
||||||
|
return getResultSetFactory().createResultSet(new CountingResultSet(source, getServiceResolver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
public class EPRPoolingLocalOpenResultSetFactoryImpl extends LocalOpenResultSetFactoryImpl {
|
||||||
|
private ResultSetEPRPool pool;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference registerResultSet(ResultSet resultSet) {
|
||||||
|
return pool.registerResultSet(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetEPRPool getPool() {
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setPool(ResultSetEPRPool pool) {
|
||||||
|
this.pool = pool;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
public class EPRPoolingLocalResultSetFactoryImpl extends LocalResultSetFactoryImpl {
|
||||||
|
|
||||||
|
private ResultSetEPRPool pool;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference registerResultSet(ResultSet resultSet) {
|
||||||
|
return pool.registerResultSet(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetEPRPool getPool() {
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setPool(ResultSetEPRPool pool) {
|
||||||
|
this.pool = pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a LinkedList populated by a given iterable, which provides a fetch window of elements
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* The FetchList type
|
||||||
|
*/
|
||||||
|
public class FetchList<T> extends LinkedList<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 7135272008563693321L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* represents the number of elements ready to be pulled out of the list
|
||||||
|
*/
|
||||||
|
private int fetchSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* represents the number of elements already consumed by a poll call
|
||||||
|
*/
|
||||||
|
private int consumedElements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the given itarable used to populate the list
|
||||||
|
*/
|
||||||
|
private Iterator<T> iter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iter
|
||||||
|
* @param fetchSize
|
||||||
|
*/
|
||||||
|
public FetchList(final Iterator<T> iter, final int fetchSize) {
|
||||||
|
super();
|
||||||
|
this.consumedElements = 0;
|
||||||
|
this.fetchSize = fetchSize;
|
||||||
|
this.iter = iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to fill the list
|
||||||
|
*/
|
||||||
|
public synchronized void fill() {
|
||||||
|
for (int i = 0; i < fetchSize; i++) {
|
||||||
|
if (!iter.hasNext()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.add(iter.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the first element and makes the list to be filled in case its size is zero
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public T poll() {
|
||||||
|
if (this.isEmpty()) {
|
||||||
|
fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.size() > 0) {
|
||||||
|
consumedElements++;
|
||||||
|
return super.poll();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of elements already consumed by a "poll"
|
||||||
|
*/
|
||||||
|
public int getConsumedElements() {
|
||||||
|
return consumedElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the actual number of elements of the list
|
||||||
|
*/
|
||||||
|
public int getTotalElements() {
|
||||||
|
return consumedElements + this.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to provide an actual size, fills the list if there are elements to fill it
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
if (this.isEmpty() && iter.hasNext()) {
|
||||||
|
fill();
|
||||||
|
}
|
||||||
|
return super.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return super.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an open ResultSet that can be iterated to get it's data results.
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IterableResultSet implements ResultSetListener, ResultSetAware {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(IterableResultSet.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the container for the data results.
|
||||||
|
*/
|
||||||
|
private ResultSet resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the list that provides data for this resultSet.
|
||||||
|
*/
|
||||||
|
private FetchList<String> fetchList;
|
||||||
|
|
||||||
|
private int optionalNumberOfElements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param iter
|
||||||
|
* @param fetchSize
|
||||||
|
*/
|
||||||
|
protected IterableResultSet(Iterable<String> iter, int fetchSize) {
|
||||||
|
fetchList = new FetchList<String>(iter.iterator(), fetchSize);
|
||||||
|
if (iter instanceof SizedIterable<?>) {
|
||||||
|
optionalNumberOfElements = ((SizedIterable<?>) iter).getNumberOfElements();
|
||||||
|
} else {
|
||||||
|
optionalNumberOfElements = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fromPosition
|
||||||
|
* @param toPosition
|
||||||
|
* @return <T> List
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(int fromPosition, int toPosition) {
|
||||||
|
|
||||||
|
log.debug(" - getting result from " + fromPosition + " to " + toPosition + ", consumedElements: " + fetchList.getConsumedElements());
|
||||||
|
|
||||||
|
if (fromPosition != fetchList.getConsumedElements() + 1)
|
||||||
|
throw new RuntimeException("Unexpected value for 'fromPosition' parameter");
|
||||||
|
if (toPosition < fromPosition)
|
||||||
|
throw new RuntimeException("'fromPosition' must be lower or equal than 'toPosition'");
|
||||||
|
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (int i = fromPosition; i <= toPosition; i++) {
|
||||||
|
if (fetchList.size() > 0)
|
||||||
|
result.add(fetchList.poll());
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureClosed();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureClosed() {
|
||||||
|
if (fetchList.size() == 0 && resultSet.isOpen()) {
|
||||||
|
log.info(">>>>>>>>>>> closing resultset <<<<<<<<<<<<<");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRSStatus() {
|
||||||
|
if (resultSet.isOpen())
|
||||||
|
return "open";
|
||||||
|
return "closed";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
ensureClosed();
|
||||||
|
|
||||||
|
if (optionalNumberOfElements == -1)
|
||||||
|
return fetchList.getTotalElements();
|
||||||
|
else
|
||||||
|
return optionalNumberOfElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes the resultset.
|
||||||
|
*/
|
||||||
|
protected void close() {
|
||||||
|
resultSet.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResultSet(ResultSet resultSet) {
|
||||||
|
this.resultSet = resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IterableResultSetFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ResultSetFactory}
|
||||||
|
*/
|
||||||
|
private LocalOpenResultSetFactoryImpl resultSetFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private int fetchSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createIterableResultSet(final Iterable<String> source) {
|
||||||
|
return resultSetFactory.createResultSet(new IterableResultSet(source, fetchSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public LocalOpenResultSetFactoryImpl getResultSetFactory() {
|
||||||
|
return resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param resultSetFactory
|
||||||
|
*/
|
||||||
|
@Required
|
||||||
|
public void setResultSetFactory(final LocalOpenResultSetFactoryImpl resultSetFactory) {
|
||||||
|
this.resultSetFactory = resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fetchSize
|
||||||
|
*/
|
||||||
|
@Required
|
||||||
|
public void setFetchSize(int fetchSize) {
|
||||||
|
this.fetchSize = fetchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getFetchSize() {
|
||||||
|
return fetchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.collections.MappedCollection;
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
import eu.dnetlib.miscutils.jaxb.JaxbFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a jaxb factory for a given type, wraps TypedResultsetListeners to ResultSetListeners, serializing objects
|
||||||
|
* according to the jaxb factory.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public class JaxbResultsetListenerWrapper<T> {
|
||||||
|
private static final Log log = LogFactory.getLog(JaxbResultsetListenerWrapper.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
private JaxbFactory<T> factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a listener which serializes each item according to the jaxb factory.
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
* listener which returns T
|
||||||
|
* @return listener which returns strings
|
||||||
|
*/
|
||||||
|
public ResultSetListener wrap(final TypedResultSetListener<T> listener) {
|
||||||
|
return new ResultSetListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(final int fromPosition, final int toPosition) {
|
||||||
|
return Lists.newArrayList(new MappedCollection<String, T>(listener.getResult(fromPosition, toPosition), new UnaryFunction<String, T>() {
|
||||||
|
@Override
|
||||||
|
public String evaluate(final T value) {
|
||||||
|
try {
|
||||||
|
return factory.serialize(value);
|
||||||
|
} catch (final JAXBException e) {
|
||||||
|
log.warn("cannot serialize", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return listener.getSize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public JaxbFactory<T> getFactory() {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFactory(final JaxbFactory<T> factory) {
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an "open" (unbounded, unfreezed) local resultset.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LocalOpenResultSetFactoryImpl extends LocalResultSetFactoryImpl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.LocalResultSetFactoryImpl#createInstance(eu.dnetlib.enabling.resultset.ResultSetListener)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected LocalResultSetImpl createInstance(final ResultSetListener provider) {
|
||||||
|
final LocalResultSetImpl instance = super.createInstance(provider);
|
||||||
|
instance.setOpen(true);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates resultset bound to a given resultset registry shared with a resultset service which exposed them
|
||||||
|
* to the outside world.
|
||||||
|
*
|
||||||
|
* It's tightly coupled with a local instance of the ResultSetService.
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetServiceImpl
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LocalResultSetFactoryImpl extends AbstractResultSetFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetFactory#createResultSet(eu.dnetlib.enabling.resultset.ResultSetListener)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference createResultSet(final ResultSetListener provider) {
|
||||||
|
return registerResultSet(createInstance(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new local resultset instance. Subclasses may override this to supply additional configuration.
|
||||||
|
*
|
||||||
|
* @param provider provider
|
||||||
|
* @return a new resultset instance.
|
||||||
|
*/
|
||||||
|
protected LocalResultSetImpl createInstance(final ResultSetListener provider) {
|
||||||
|
return new LocalResultSetImpl(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resultset backing implementation.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LocalResultSetImpl extends AbstractObservableResultset implements ResultSet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsId.
|
||||||
|
*/
|
||||||
|
private String identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this listener will provide the data to this local resultset by listening to events.
|
||||||
|
*/
|
||||||
|
private ResultSetListener listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new local ResultSet which pulls data from the listener. If the listener implements ResultSetAware, it
|
||||||
|
* will be injected with this instance.
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
* a resultset listener
|
||||||
|
*/
|
||||||
|
public LocalResultSetImpl(final ResultSetListener listener) {
|
||||||
|
super();
|
||||||
|
this.listener = listener;
|
||||||
|
|
||||||
|
if (listener instanceof ResultSetAware)
|
||||||
|
((ResultSetAware) listener).setResultSet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSet#getNumberOfResults()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getNumberOfResults() {
|
||||||
|
return listener.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSet#getResults(int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResults(final int fromPosition, final int toPosition) {
|
||||||
|
int toPos = toPosition;
|
||||||
|
int fromPos = fromPosition;
|
||||||
|
if (!isOpen()) {
|
||||||
|
final int size = getNumberOfResults();
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return Lists.newArrayList();
|
||||||
|
|
||||||
|
if (fromPos > size)
|
||||||
|
return Lists.newArrayList();
|
||||||
|
|
||||||
|
if (toPos > size)
|
||||||
|
toPos = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromPos < 1)
|
||||||
|
fromPos = 1;
|
||||||
|
if (toPos < fromPos)
|
||||||
|
toPos = fromPos;
|
||||||
|
|
||||||
|
return listener.getResult(fromPos, toPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIdentifier(final String identifier) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetListener getListener() {
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(final ResultSetListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
import eu.dnetlib.miscutils.collections.MappedCollection;
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A resultset filter. Applies a transformation for every resultset record.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MappedResultSet implements ResultSetListener, ResultSetAware {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* input resultset.
|
||||||
|
*/
|
||||||
|
private ResultSetService resultSetService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* input resultset id.
|
||||||
|
*/
|
||||||
|
private String rsId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mapper function.
|
||||||
|
*/
|
||||||
|
private UnaryFunction<String, String> mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* service resolver.
|
||||||
|
*/
|
||||||
|
private ServiceResolver serviceResolver;
|
||||||
|
|
||||||
|
private ResultSet resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new mapped resultset.
|
||||||
|
*
|
||||||
|
* @param epr
|
||||||
|
* input resultset epr
|
||||||
|
* @param mapper
|
||||||
|
* mapper function
|
||||||
|
* @param serviceResolver
|
||||||
|
* service resolver
|
||||||
|
*/
|
||||||
|
public MappedResultSet(final W3CEndpointReference epr, final UnaryFunction<String, String> mapper, final ServiceResolver serviceResolver) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.resultSetService = serviceResolver.getService(ResultSetService.class, epr);
|
||||||
|
this.rsId = serviceResolver.getResourceIdentifier(epr);
|
||||||
|
|
||||||
|
this.mapper = mapper;
|
||||||
|
|
||||||
|
this.serviceResolver = serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetListener#getResult(int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(final int fromPosition, final int toPosition) {
|
||||||
|
return MappedCollection.listMap(getResultFromSource(fromPosition, toPosition), mapper);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> getResultFromSource(final int fromPosition, final int toPosition) {
|
||||||
|
try {
|
||||||
|
List<String> res = resultSetService.getResult(rsId, fromPosition, toPosition, "waiting");
|
||||||
|
checkStatus();
|
||||||
|
return res;
|
||||||
|
} catch (final ResultSetException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkStatus() throws ResultSetException {
|
||||||
|
if (getResultSet().isOpen() && resultSetService.getRSStatus(rsId).equals("closed")) {
|
||||||
|
getResultSet().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetListener#getSize()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
try {
|
||||||
|
int numberOfElements = resultSetService.getNumberOfElements(rsId);
|
||||||
|
checkStatus();
|
||||||
|
return numberOfElements;
|
||||||
|
} catch (final ResultSetException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetService getResultSetService() {
|
||||||
|
return resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSetService(final ResultSetService resultSetService) {
|
||||||
|
this.resultSetService = resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnaryFunction<String, String> getMapper() {
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapper(final UnaryFunction<String, String> mapper) {
|
||||||
|
this.mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceResolver getServiceResolver() {
|
||||||
|
return serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setServiceResolver(final ServiceResolver serviceResolver) {
|
||||||
|
this.serviceResolver = serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResultSet(ResultSet resultSet) {
|
||||||
|
this.resultSet = resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRsId() {
|
||||||
|
return rsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRsId(String rsId) {
|
||||||
|
this.rsId = rsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new resultset which takes each record of the input resultset and applies the mapping function to it.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MappedResultSetFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* underlying resultset factory, which exposes local resultsets to the world.
|
||||||
|
*/
|
||||||
|
private ResultSetFactory resultSetFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* service resolver, transforms eprs to services.
|
||||||
|
*/
|
||||||
|
private ServiceResolver serviceResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new resultset which takes each record of the input resultset and applies the mapping function to it.
|
||||||
|
*
|
||||||
|
* @param source source resultset epr
|
||||||
|
* @param mapper mapper function
|
||||||
|
* @return mapped resultset epr
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final UnaryFunction<String, String> mapper) {
|
||||||
|
return resultSetFactory.createResultSet(new MappedResultSet(source, mapper, serviceResolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetFactory getResultSetFactory() {
|
||||||
|
return resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSetFactory(final ResultSetFactory resultSetFactory) {
|
||||||
|
this.resultSetFactory = resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceResolver getServiceResolver() {
|
||||||
|
return serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceResolver(final ServiceResolver serviceResolver) {
|
||||||
|
this.serviceResolver = serviceResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
import eu.dnetlib.miscutils.collections.MappedCollection;
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
|
||||||
|
public class ParallelMappedResultSet extends MappedResultSet {
|
||||||
|
|
||||||
|
private ExecutorService executor;
|
||||||
|
|
||||||
|
public ParallelMappedResultSet(final W3CEndpointReference source, final UnaryFunction<String, String> mapper, final ServiceResolver serviceResolver,
|
||||||
|
final ExecutorService executor) {
|
||||||
|
super(source, mapper, serviceResolver);
|
||||||
|
this.executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(int fromPosition, int toPosition) {
|
||||||
|
|
||||||
|
// log.info("Parallel page " + (toPosition - fromPosition + 1));
|
||||||
|
|
||||||
|
List<Future<String>> results = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (final String input : getResultFromSource(fromPosition, toPosition)) {
|
||||||
|
results.add(executor.submit(new Callable<String>() {
|
||||||
|
@Override
|
||||||
|
public String call() throws Exception {
|
||||||
|
return getMapper().evaluate(input);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MappedCollection.listMap(results, new UnaryFunction<String, Future<String>>() {
|
||||||
|
@Override
|
||||||
|
public String evaluate(Future<String> arg) {
|
||||||
|
try {
|
||||||
|
return arg.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
|
||||||
|
public class ParallelMappedResultSetFactory extends MappedResultSetFactory {
|
||||||
|
|
||||||
|
private ExecutorService executor;
|
||||||
|
|
||||||
|
private static final int QUEUE_SIZE = 40;
|
||||||
|
|
||||||
|
private int queueSize = QUEUE_SIZE;
|
||||||
|
|
||||||
|
private int cpus = 0;
|
||||||
|
|
||||||
|
public ParallelMappedResultSetFactory() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
if (cpus == 0)
|
||||||
|
cpus = getNumberOfCPUs();
|
||||||
|
executor = new ThreadPoolExecutor(cpus, cpus, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize),
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final UnaryFunction<String, String> mapper) {
|
||||||
|
return getResultSetFactory().createResultSet(new ParallelMappedResultSet(source, mapper, getServiceResolver(), executor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNumberOfCPUs() {
|
||||||
|
return Runtime.getRuntime().availableProcessors();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCpus() {
|
||||||
|
return cpus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCpus(int cpus) {
|
||||||
|
if(cpus > 0)
|
||||||
|
this.cpus = cpus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.observer.Observable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ResultSet represents a set of data results.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSet extends Observable {
|
||||||
|
/**
|
||||||
|
* get the resource identifier.
|
||||||
|
*
|
||||||
|
* @return rsId
|
||||||
|
*/
|
||||||
|
String getIdentifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the resource identifier. The ResultSetRegistry will assign a new rsId.
|
||||||
|
*
|
||||||
|
* @param rsId allocated resultset identifier
|
||||||
|
*/
|
||||||
|
void setIdentifier(String rsId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a 'page' of results.
|
||||||
|
*
|
||||||
|
* @param fromPosition
|
||||||
|
* from 1
|
||||||
|
* @param toPosition
|
||||||
|
* last included
|
||||||
|
* @return a page of data
|
||||||
|
*/
|
||||||
|
List<String> getResults(int fromPosition, int toPosition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the number of result elements present in the resultset.
|
||||||
|
*
|
||||||
|
* @return number of results
|
||||||
|
*/
|
||||||
|
int getNumberOfResults();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if the resultset is open or closed.
|
||||||
|
*
|
||||||
|
* @return true if open
|
||||||
|
*/
|
||||||
|
boolean isOpen();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close a resultset.
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if the resultset is destroyed.
|
||||||
|
*
|
||||||
|
* @return true if the resultset is destroyed.
|
||||||
|
*/
|
||||||
|
boolean isDestroyed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the resultset and free associated resources, remove it from the ResultSetRegistry.
|
||||||
|
* After calling this method, the resultset is no more accessible from other services.
|
||||||
|
*/
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResultSet listeners can add this interface in order to receive the ResultSet they are bound to.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSetAware {
|
||||||
|
/**
|
||||||
|
* sets the resultset instance.
|
||||||
|
*
|
||||||
|
* @param resultSet the resultset instance
|
||||||
|
*/
|
||||||
|
void setResultSet(ResultSet resultSet);
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.tools.UniqueIdentifierGenerator;
|
||||||
|
import eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl;
|
||||||
|
|
||||||
|
public class ResultSetEPRPool {
|
||||||
|
private static final Log log = LogFactory.getLog(ResultSetEPRPool.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
static class PreparedResultSet {
|
||||||
|
private String rsId;
|
||||||
|
private W3CEndpointReference epr;
|
||||||
|
|
||||||
|
public PreparedResultSet(final String rsId, final W3CEndpointReference epr) {
|
||||||
|
super();
|
||||||
|
this.rsId = rsId;
|
||||||
|
this.epr = epr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRsId() {
|
||||||
|
return rsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRsId(final String rsId) {
|
||||||
|
this.rsId = rsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public W3CEndpointReference getEpr() {
|
||||||
|
return epr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEpr(final W3CEndpointReference epr) {
|
||||||
|
this.epr = epr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PoolFiller implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true)
|
||||||
|
try {
|
||||||
|
final PreparedResultSet resultSet = prepareResultSet();
|
||||||
|
pool.put(resultSet);
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
// eat this exception
|
||||||
|
log.debug("cannot add resultset to pool", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PreparedResultSet prepareResultSet() {
|
||||||
|
final String rsId = idGenerator.generateIdentifier();
|
||||||
|
return new PreparedResultSet(rsId, createEPR(rsId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private W3CEndpointReference createEPR(final String rsId) {
|
||||||
|
return getResultSetService().getEprBuilder().getEndpointReference(getResultSetService().getEndpoint(), rsId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset service.
|
||||||
|
*/
|
||||||
|
private ResultSetServiceImpl resultSetService;
|
||||||
|
|
||||||
|
private int capacity = 1000;
|
||||||
|
private int fillerThreads = 10;
|
||||||
|
private final BlockingQueue<PreparedResultSet> pool = new LinkedBlockingQueue<PreparedResultSet>(capacity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* identifier generator.
|
||||||
|
*/
|
||||||
|
private UniqueIdentifierGenerator idGenerator = new UniqueIdentifierGeneratorImpl("rs-");
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
log.info("-------<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>> Starting fill threads");
|
||||||
|
for (int i = 0; i < fillerThreads; i++)
|
||||||
|
startFillter();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startFillter() {
|
||||||
|
final Thread filler = new Thread(new PoolFiller());
|
||||||
|
filler.setDaemon(true);
|
||||||
|
filler.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public W3CEndpointReference registerResultSet(final ResultSet resultSet) {
|
||||||
|
final PreparedResultSet prepared = nextPreparedResultSet();
|
||||||
|
if (prepared == null) {
|
||||||
|
log.info("EPR cache is empty, creating EPR in caller thread");
|
||||||
|
return getResultSetService().getEprBuilder().getEndpointReference(getResultSetService().getEndpoint(), idGenerator.generateIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
getResultSetService().getResultsetRegistry().addResultSet(resultSet, prepared.getRsId());
|
||||||
|
return prepared.getEpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PreparedResultSet nextPreparedResultSet() {
|
||||||
|
log.info(">>>> fetching a prepared resultset from the pool");
|
||||||
|
return pool.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCapacity() {
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCapacity(int capacity) {
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniqueIdentifierGenerator getIdGenerator() {
|
||||||
|
return idGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdGenerator(UniqueIdentifierGenerator idGenerator) {
|
||||||
|
this.idGenerator = idGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetServiceImpl getResultSetService() {
|
||||||
|
return resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setResultSetService(ResultSetServiceImpl resultSetService) {
|
||||||
|
this.resultSetService = resultSetService;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a resultset service from a producer.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSetFactory {
|
||||||
|
/**
|
||||||
|
* TODO other parameters like expiration time etc.
|
||||||
|
*
|
||||||
|
* @param provider a resultset listener which provides the data
|
||||||
|
* @return an EPR to the resultset.
|
||||||
|
*/
|
||||||
|
W3CEndpointReference createResultSet(ResultSetListener provider);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ResultSetListener is a pull interface to a ResultSet.
|
||||||
|
*
|
||||||
|
* The Resultset will call method of ResultSetListener implementors whenever it needs to pull some data and provide it
|
||||||
|
* to clients. The ResultSet service acts as a decouple point between the producer and the consumer.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSetListener extends TypedResultSetListener<String> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* access resultset properties.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSetPropertyDao {
|
||||||
|
/**
|
||||||
|
* return a map of custom resultset properties.
|
||||||
|
*
|
||||||
|
* @param resultSet resultset
|
||||||
|
* @return property map
|
||||||
|
*/
|
||||||
|
Map<String, String> getProperties(ResultSet resultSet);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fake resultset property dao.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResultSetPropertyDaoImpl implements ResultSetPropertyDao {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetPropertyDao#getProperties(eu.dnetlib.enabling.resultset.ResultSet)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getProperties(final ResultSet resultSet) {
|
||||||
|
return new HashMap<String, String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.observer.ResultSetObserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instances of ResultSetRegistry manage a set of resultset objects and manage their garbage collection.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSetRegistry extends ResultSetObserver {
|
||||||
|
/**
|
||||||
|
* add a resultset object to the registry.
|
||||||
|
*
|
||||||
|
* The given resultset object from now on is managed by the resultset registry.
|
||||||
|
*
|
||||||
|
* @param resultSet
|
||||||
|
* a resultset object
|
||||||
|
*/
|
||||||
|
void addResultSet(ResultSet resultSet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a resultset object to the registry.
|
||||||
|
*
|
||||||
|
* The given resultset object from now on is managed by the resultset registry.
|
||||||
|
*
|
||||||
|
* @param resultSet
|
||||||
|
* a resultset object
|
||||||
|
* @param identifier the identifier you want for the resultset
|
||||||
|
*/
|
||||||
|
void addResultSet(ResultSet resultSet, String identifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a resultset object to the registry.
|
||||||
|
*
|
||||||
|
* The given resultset object from now on is managed by the resultset registry.
|
||||||
|
*
|
||||||
|
* @param resultSet
|
||||||
|
* a resultset object
|
||||||
|
* @param maxIdleTime
|
||||||
|
* max idle time
|
||||||
|
*/
|
||||||
|
void addResultSet(ResultSet resultSet, int maxIdleTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a resultset object to the registry.
|
||||||
|
*
|
||||||
|
* The given resultset object from now on is managed by the resultset registry.
|
||||||
|
*
|
||||||
|
* @param resultSet
|
||||||
|
* a resultset object
|
||||||
|
* @param identifier the identifier you want for the resultset
|
||||||
|
* @param maxIdleTime max idle time
|
||||||
|
*/
|
||||||
|
void addResultSet(ResultSet resultSet, String identifier, int maxIdleTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obtain the resultset with the given id.
|
||||||
|
*
|
||||||
|
* @param rsId
|
||||||
|
* resultset id
|
||||||
|
* @return the resultset object matching the rsId or null
|
||||||
|
*/
|
||||||
|
ResultSet getResultSetById(String rsId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obtain the resultset's maxIdleTime parameter for a resultset with the given id.
|
||||||
|
*
|
||||||
|
* @param rsId
|
||||||
|
* resultset id
|
||||||
|
* @return max idle time in seconds, as specified when the resultset has been registered
|
||||||
|
*/
|
||||||
|
int getMaxIdleTimeById(String rsId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.tools.UniqueIdentifierGenerator;
|
||||||
|
import eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl;
|
||||||
|
import eu.dnetlib.miscutils.cache.Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement a in memory resultset registry.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResultSetRegistryImpl implements ResultSetRegistry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsId -> ResultSet mappings are stored here.
|
||||||
|
*/
|
||||||
|
private Cache<String, ResultSet> cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsID -> initial maxIdleTime time are store here.
|
||||||
|
*/
|
||||||
|
private Cache<String, Integer> maxIdleTimeCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* identifier generator.
|
||||||
|
*/
|
||||||
|
private UniqueIdentifierGenerator idGenerator = new UniqueIdentifierGeneratorImpl("rs-");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addResultSet(final ResultSet resultSet) {
|
||||||
|
addResultSet(resultSet, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addResultSet(final ResultSet resultSet, final String identifier) {
|
||||||
|
addResultSet(resultSet, identifier, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addResultSet(final ResultSet resultSet, final int maxIdleTime) {
|
||||||
|
addResultSet(resultSet, idGenerator.generateIdentifier(), maxIdleTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, java.lang.String, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addResultSet(final ResultSet resultSet, final String identifier, final int maxIdleTime) {
|
||||||
|
resultSet.setIdentifier(identifier);
|
||||||
|
resultSet.addObserver(this);
|
||||||
|
cache.put(resultSet.getIdentifier(), resultSet);
|
||||||
|
maxIdleTimeCache.put(resultSet.getIdentifier(), maxIdleTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#getResultSetById(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResultSet getResultSetById(final String rsId) {
|
||||||
|
return cache.get(rsId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxIdleTimeById(final String rsId) {
|
||||||
|
return maxIdleTimeCache.get(rsId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Cache<String, ResultSet> getCache() {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setCache(final Cache<String, ResultSet> cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.miscutils.observer.Observer#update(eu.dnetlib.enabling.resultset.observer.Observable, java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update(final ResultSet observed, final Object arg) {
|
||||||
|
if (!observed.isOpen())
|
||||||
|
cache.remove(observed.getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniqueIdentifierGenerator getIdGenerator() {
|
||||||
|
return idGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdGenerator(final UniqueIdentifierGenerator idGenerator) {
|
||||||
|
this.idGenerator = idGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, Integer> getMaxIdleTimeCache() {
|
||||||
|
return maxIdleTimeCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setMaxIdleTimeCache(Cache<String, Integer> maxIdleTimeCache) {
|
||||||
|
this.maxIdleTimeCache = maxIdleTimeCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.jws.WebService;
|
||||||
|
import javax.xml.ws.Endpoint;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.common.rmi.UnimplementedException;
|
||||||
|
import eu.dnetlib.enabling.resultset.push.PushResultSet;
|
||||||
|
import eu.dnetlib.enabling.resultset.push.PushResultSetFactory;
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||||
|
import eu.dnetlib.enabling.tools.AbstractBaseService;
|
||||||
|
import eu.dnetlib.soap.EndpointReferenceBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component dispatches the service method calls to stateful datastructure instances and to the singleton core.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@WebService(targetNamespace = "http://services.dnetlib.eu/")
|
||||||
|
public class ResultSetServiceImpl extends AbstractBaseService implements ResultSetService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(ResultSetServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps resultset identifiers to resultsets and manages expiration etc.
|
||||||
|
*/
|
||||||
|
private ResultSetRegistry resultsetRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* push resultset factory.
|
||||||
|
*/
|
||||||
|
private PushResultSetFactory pushFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service endpoint.
|
||||||
|
*/
|
||||||
|
private Endpoint endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* injected epr builder.
|
||||||
|
*/
|
||||||
|
private EndpointReferenceBuilder<Endpoint> eprBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* custom resultset properties.
|
||||||
|
*/
|
||||||
|
private ResultSetPropertyDao customPropertyDao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#closeRS(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void closeRS(final String rsId) {
|
||||||
|
try {
|
||||||
|
final ResultSet resultSet = getResultSetById(rsId);
|
||||||
|
resultSet.close();
|
||||||
|
} catch (ResultSetException e) {
|
||||||
|
log.warn("should throw checked exception but wasn't declared in cnr-rmi-api", e);
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPullRS(java.lang.String, java.lang.String, int, int, java.lang.String,
|
||||||
|
* java.lang.Integer, java.lang.Integer)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference createPullRS(final String providerAddress,
|
||||||
|
final String bdId,
|
||||||
|
final int initialPageSize,
|
||||||
|
final int expiryTime,
|
||||||
|
final String styleSheet,
|
||||||
|
final Integer keepAliveTime,
|
||||||
|
final Integer total) {
|
||||||
|
throw new UnimplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPullRSEPR(javax.xml.ws.wsaddressing.W3CEndpointReference,
|
||||||
|
* java.lang.String, int, int, java.lang.String, java.lang.Integer, java.lang.Integer)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference createPullRSEPR(final W3CEndpointReference dataProviderEPR,
|
||||||
|
final String bdId,
|
||||||
|
final int initialPageSize,
|
||||||
|
final int expiryTime,
|
||||||
|
final String styleSheet,
|
||||||
|
final Integer keepAliveTime,
|
||||||
|
final Integer total) {
|
||||||
|
throw new UnimplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getNumberOfElements(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getNumberOfElements(final String rsId) throws ResultSetException {
|
||||||
|
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||||
|
return resultSet.getNumberOfResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getResult(java.lang.String, int, int, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(final String rsId, final int fromPosition, final int toPosition, final String requestMode) throws ResultSetException {
|
||||||
|
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||||
|
return resultSet.getResults(fromPosition, toPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPushRS(int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference createPushRS(final int expiryTime, final int keepAliveTime) throws ResultSetException {
|
||||||
|
return pushFactory.createPushResultSet(expiryTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getProperty(java.lang.String, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getProperty(final String rsId, final String name) throws ResultSetException {
|
||||||
|
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||||
|
|
||||||
|
if ("rsId".equals(name)) return resultSet.getIdentifier();
|
||||||
|
else if ("total".equals(name)) return Integer.toString(resultSet.getNumberOfResults());
|
||||||
|
else if ("maxExpiryTime".equals(name)) return Integer.toString(resultsetRegistry.getMaxIdleTimeById(rsId));
|
||||||
|
else if ("expiryTime".equals(name)) return Integer.toString(resultsetRegistry.getMaxIdleTimeById(rsId));
|
||||||
|
else if ("keepAliveTime".equals(name)) return Integer.toString(resultsetRegistry.getMaxIdleTimeById(rsId));
|
||||||
|
else if ("classSimpleName".equals(name)) return resultSet.getClass().getSimpleName();
|
||||||
|
// ...
|
||||||
|
|
||||||
|
return customPropertyDao.getProperties(resultSet).get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getRSStatus(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getRSStatus(final String rsId) throws ResultSetException {
|
||||||
|
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||||
|
if (resultSet.isOpen()) return "open";
|
||||||
|
return "closed";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#populateRS(java.lang.String, java.util.List)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String populateRS(final String rsId, final List<String> elements) throws ResultSetException {
|
||||||
|
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||||
|
if (resultSet instanceof PushResultSet) {
|
||||||
|
((PushResultSet) resultSet).addElements(elements);
|
||||||
|
} else throw new ResultSetException("ResultSet '" + rsId + "' is not a push resultset");
|
||||||
|
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.common.rmi.BaseService#start()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obtain the resultset object for a given id.
|
||||||
|
*
|
||||||
|
* @param rsId
|
||||||
|
* resultset id
|
||||||
|
* @return resultset object, never null
|
||||||
|
* @throws ResultSetException
|
||||||
|
* thrown when the id doesn't exist;
|
||||||
|
*/
|
||||||
|
private ResultSet getResultSetById(final String rsId) throws ResultSetException {
|
||||||
|
final ResultSet resultSet = resultsetRegistry.getResultSetById(rsId); // NOPMD
|
||||||
|
if (resultSet == null) throw new ResultSetException("resultset with id '" + rsId + "' doesn't exist");
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetRegistry getResultsetRegistry() {
|
||||||
|
return resultsetRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setResultsetRegistry(final ResultSetRegistry resultsetRegistry) {
|
||||||
|
this.resultsetRegistry = resultsetRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndpointReferenceBuilder<Endpoint> getEprBuilder() {
|
||||||
|
return eprBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setEprBuilder(final EndpointReferenceBuilder<Endpoint> eprBuilder) {
|
||||||
|
this.eprBuilder = eprBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Endpoint getEndpoint() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setEndpoint(final Endpoint endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PushResultSetFactory getPushFactory() {
|
||||||
|
return pushFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setPushFactory(final PushResultSetFactory pushFactory) {
|
||||||
|
this.pushFactory = pushFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSetPropertyDao getCustomPropertyDao() {
|
||||||
|
return customPropertyDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomPropertyDao(final ResultSetPropertyDao customPropertyDao) {
|
||||||
|
this.customPropertyDao = customPropertyDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
public interface SizedIterable<T> extends Iterable<T> {
|
||||||
|
|
||||||
|
public int getNumberOfElements();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
public class StreamingResultSetFactory {
|
||||||
|
/**
|
||||||
|
* underlying resultset factory, which exposes local resultsets to the world.
|
||||||
|
*/
|
||||||
|
private ResultSetFactory resultSetFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param items
|
||||||
|
* @param size the size of the iterable
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createStreamingResultSet(final Iterable<String> items, int size) {
|
||||||
|
return resultSetFactory.createResultSet(new StreamingResultSetListener(items.iterator(), size));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ResultSetFactory getResultSetFactory() {
|
||||||
|
return resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setResultSetFactory(ResultSetFactory resultSetFactory) {
|
||||||
|
this.resultSetFactory = resultSetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes an iterable through our resultset protocol.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The resultset protocol is constructed as if it were random access. Some kind of sources, like an iterable, is not
|
||||||
|
* random access. The consumer of such a resultset knows that, and won't try to access the resultset randomly. However,
|
||||||
|
* it could ask for some data which is already sent, because of retries caused by network issues.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class StreamingResultSetListener implements ResultSetListener, ResultSetAware {
|
||||||
|
private static final Log log = LogFactory.getLog(StreamingResultSetListener.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
private ResultSet resultSet;
|
||||||
|
|
||||||
|
private Iterable<String> iterable;
|
||||||
|
private Iterator<String> items;
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
private int lastFrom = 0;
|
||||||
|
private int lastTo = 0;
|
||||||
|
private List<String> lastChunk;
|
||||||
|
|
||||||
|
public StreamingResultSetListener(Iterable<String> items, int size) {
|
||||||
|
this(items.iterator(), size);
|
||||||
|
this.iterable = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamingResultSetListener(Iterator<String> items, int size) {
|
||||||
|
super();
|
||||||
|
this.items = items;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reset() {
|
||||||
|
lastFrom = 0;
|
||||||
|
items = iterable.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(int from, int to) {
|
||||||
|
|
||||||
|
log.debug("STREAM: getResult(" + from + ", " + to + ")");
|
||||||
|
|
||||||
|
// handle retry because of network error.
|
||||||
|
if (from == lastFrom && to == lastTo)
|
||||||
|
return lastChunk;
|
||||||
|
|
||||||
|
if (from != lastTo + 1) {
|
||||||
|
if (from == 1 && iterable != null)
|
||||||
|
reset();
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException("this resultset is not random access, you can only retry last chunk only, asked from " + from + " to "
|
||||||
|
+ to + " but lastTo = " + lastTo + ". Size = " + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> chunk = new ArrayList<String>();
|
||||||
|
for (int i = from; i <= to; i++)
|
||||||
|
chunk.add(items.next());
|
||||||
|
|
||||||
|
if (resultSet != null && !items.hasNext())
|
||||||
|
resultSet.close();
|
||||||
|
|
||||||
|
lastFrom = from;
|
||||||
|
lastTo = to;
|
||||||
|
lastChunk = chunk;
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<String> getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(Iterator<String> items) {
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastFrom() {
|
||||||
|
return lastFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastFrom(int lastFrom) {
|
||||||
|
this.lastFrom = lastFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastTo() {
|
||||||
|
return lastTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastTo(int lastTo) {
|
||||||
|
this.lastTo = lastTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getLastChunk() {
|
||||||
|
return lastChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastChunk(List<String> lastChunk) {
|
||||||
|
this.lastChunk = lastChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResultSet(ResultSet resultSet) {
|
||||||
|
this.resultSet = resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A TypedResultSetListener is a pull interface to a ResultSet.
|
||||||
|
*
|
||||||
|
* The Resultset will call method of ResultSetListener implementors whenever it needs to pull some data and provide it
|
||||||
|
* to clients. The ResultSet service acts as a decouple point between the producer and the consumer.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface TypedResultSetListener<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a single page of results.
|
||||||
|
*
|
||||||
|
* @param fromPosition
|
||||||
|
* from 1
|
||||||
|
* @param toPosition
|
||||||
|
* last included
|
||||||
|
* @return page of results
|
||||||
|
*/
|
||||||
|
List<T> getResult(int fromPosition, int toPosition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get number of elements.
|
||||||
|
*
|
||||||
|
* @return number of elements
|
||||||
|
*/
|
||||||
|
int getSize();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.xml.transform.Source;
|
||||||
|
import javax.xml.transform.TransformerConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerFactoryConfigurationError;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a mapped resultset using a given XSLT.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class XSLTMappedResultSetFactory extends MappedResultSetFactory {
|
||||||
|
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final String xslt) {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a mapped resultset using a given XSLT.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* source
|
||||||
|
* @param xslt
|
||||||
|
* XSLT source
|
||||||
|
* @return epr of mapped resultset
|
||||||
|
* @throws TransformerConfigurationException
|
||||||
|
* could happen
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final String xslt, final String name)
|
||||||
|
throws TransformerConfigurationException {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Resource xslt) {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt));
|
||||||
|
}
|
||||||
|
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Source xslt) {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt));
|
||||||
|
}
|
||||||
|
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Resource xslt, final Map<String, String> parameters) {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt, parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final String xslt, final Map<String, String> parameters) {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt, "rs-" + UUID.randomUUID(), parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a mapped resultset using a given XSLT.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* source
|
||||||
|
* @param xslt
|
||||||
|
* XSLT
|
||||||
|
* @return epr of mapped resultset
|
||||||
|
* @throws TransformerFactoryConfigurationError
|
||||||
|
* @throws TransformerConfigurationException
|
||||||
|
* could happen
|
||||||
|
*/
|
||||||
|
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Source xslt, final String name) {
|
||||||
|
return createMappedResultSet(source, new ApplyXslt(xslt, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.observer;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSet;
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSetRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class delegates an observation event from the java.util.Observable producer to the real consumer which is not a
|
||||||
|
* java.util.Observer (as expected by java.util.Observable) but instead a miscutils Observer.
|
||||||
|
*
|
||||||
|
* @author marko, claudio, alessia, michele
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DelegationObserver implements java.util.Observer {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private transient final ResultSet observable;
|
||||||
|
private transient final ResultSetRegistry observer;
|
||||||
|
|
||||||
|
public DelegationObserver(final ResultSet observable, final ResultSetRegistry observer) {
|
||||||
|
this.observable = observable;
|
||||||
|
this.observer = observer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(final java.util.Observable ignored, final Object arg) {
|
||||||
|
observer.update(observable, arg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.observer;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSetRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares the JDK-like standard observable pattern as a java interface.
|
||||||
|
*
|
||||||
|
* @author marko, claudio, alessia, michele
|
||||||
|
*/
|
||||||
|
public interface Observable {
|
||||||
|
/**
|
||||||
|
* add a given observer to this object.
|
||||||
|
*
|
||||||
|
* @param observer
|
||||||
|
* observer
|
||||||
|
*/
|
||||||
|
void addObserver(ResultSetRegistry observer);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.observer;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSet;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement the same interface as JDK java.util.Observer as java interface (not as a class) and introduce static type
|
||||||
|
* safeness through generics.
|
||||||
|
*
|
||||||
|
* @author marko, claudio, alessia, michele
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ResultSetObserver {
|
||||||
|
/**
|
||||||
|
* gets notified when an observed object is updated.
|
||||||
|
*
|
||||||
|
* @param observed
|
||||||
|
* observed object which modification triggered this call.
|
||||||
|
* @param arg
|
||||||
|
* arg
|
||||||
|
*/
|
||||||
|
void update(ResultSet observed, Object arg);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSetServiceImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* push resultset factory.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractPushResultSetFactoryImpl implements PushResultSetFactory {
|
||||||
|
/**
|
||||||
|
* resultset service.
|
||||||
|
*/
|
||||||
|
private ResultSetServiceImpl resultSetService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.PushResultSetFactory#createPushResultSet(int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public W3CEndpointReference createPushResultSet(final int maxIdleTime) {
|
||||||
|
final PushResultSet resultSet = newInstance();
|
||||||
|
resultSetService.getResultsetRegistry().addResultSet(resultSet, maxIdleTime);
|
||||||
|
return resultSetService.getEprBuilder().getEndpointReference(resultSetService.getEndpoint(), resultSet.getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* subclasses should override it and create a new push resultset instance.
|
||||||
|
* @return push resultset instance
|
||||||
|
*/
|
||||||
|
protected abstract PushResultSet newInstance();
|
||||||
|
|
||||||
|
public ResultSetServiceImpl getResultSetService() {
|
||||||
|
return resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSetService(final ResultSetServiceImpl resultSetService) {
|
||||||
|
this.resultSetService = resultSetService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.push.ResultSetDescriptor.Range;
|
||||||
|
import eu.dnetlib.miscutils.cache.Cache;
|
||||||
|
import eu.dnetlib.miscutils.factory.Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* implement a resultset dao.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CacheTransientResultSetDaoImpl implements TransientPushResultSetDao {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(CacheTransientResultSetDaoImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* range cache. Keys are "rsid-rangenumber".
|
||||||
|
*/
|
||||||
|
private Cache<String, List<String>> cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultsets
|
||||||
|
*/
|
||||||
|
private Cache<String, ResultSetDescriptor> resultSetCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset descriptor factory.
|
||||||
|
*/
|
||||||
|
@Resource
|
||||||
|
private Factory<ResultSetDescriptor> resultSetDescriptorFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#getSize(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getSize(final String key) {
|
||||||
|
final ResultSetDescriptor desc = resultSetCache.get(key);
|
||||||
|
if (desc == null)
|
||||||
|
return 0;
|
||||||
|
return (desc.getRanges() - 1) * desc.getRangeLength() + cache.get(key + "-" + desc.getLastRange()).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#addElements(java.lang.String, java.util.List)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addElements(final String key, final List<String> elements) {
|
||||||
|
// TODO: huuuuu, chaos, fix this please!
|
||||||
|
synchronized (cache) {
|
||||||
|
|
||||||
|
ResultSetDescriptor desc = resultSetCache.get(key);
|
||||||
|
|
||||||
|
log.debug("got desc: " + desc);
|
||||||
|
if (desc == null) {
|
||||||
|
desc = resultSetDescriptorFactory.newInstance();
|
||||||
|
resultSetCache.put(key, desc);
|
||||||
|
}
|
||||||
|
log.debug("desc now is desc: " + desc);
|
||||||
|
|
||||||
|
if (elements.size() > desc.getRangeLength())
|
||||||
|
throw new IllegalArgumentException("The current implementation of the push resultset doesn't accept pages longer than "
|
||||||
|
+ desc.getRangeLength() + ", got: " + elements.size());
|
||||||
|
|
||||||
|
|
||||||
|
int lastRangeIndex = desc.getLastRange();
|
||||||
|
|
||||||
|
if (lastRangeIndex < 0)
|
||||||
|
lastRangeIndex = 0;
|
||||||
|
|
||||||
|
log.debug("last range: " + lastRangeIndex);
|
||||||
|
|
||||||
|
List<String> lastRange = cache.get(key + "-" + lastRangeIndex);
|
||||||
|
log.debug("stored last range: " + lastRange);
|
||||||
|
|
||||||
|
if (lastRange == null) {
|
||||||
|
lastRange = new ArrayList<String>();
|
||||||
|
desc.setRanges(desc.getRanges() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("last range is: " + lastRange);
|
||||||
|
|
||||||
|
final int free = desc.getRangeLength() - lastRange.size();
|
||||||
|
log.debug("free: " + free);
|
||||||
|
log.debug("desc range length: " + desc.getRangeLength());
|
||||||
|
log.debug("last range size: " + lastRange.size());
|
||||||
|
|
||||||
|
int toElements = free;
|
||||||
|
if (toElements > elements.size()) {
|
||||||
|
toElements = elements.size();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
final List<String> nextRange = new ArrayList<String>(elements.subList(free, elements.size()));
|
||||||
|
log.debug("next range: " + nextRange);
|
||||||
|
|
||||||
|
cache.put(key + "-" + (lastRangeIndex + 1), nextRange);
|
||||||
|
log.debug("next range stored at: " + key + "-" + (lastRangeIndex + 1));
|
||||||
|
desc.setRanges(desc.getRanges() + 1);
|
||||||
|
}
|
||||||
|
lastRange.addAll(elements.subList(0, toElements));
|
||||||
|
|
||||||
|
log.debug("LAST RANGE SIZE: " + lastRange.size() + " range index " + lastRangeIndex);
|
||||||
|
|
||||||
|
log.debug("after add: " + lastRange);
|
||||||
|
|
||||||
|
cache.put(key + "-" + lastRangeIndex, lastRange);
|
||||||
|
log.debug("range stored at: " + key + "-" + lastRangeIndex);
|
||||||
|
|
||||||
|
resultSetCache.put(key, desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#getElements(java.lang.String, int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getElements(final String key, final int fromPosition, final int toPosition) {
|
||||||
|
ResultSetDescriptor desc = resultSetCache.get(key);
|
||||||
|
log.debug("got desc: " + desc);
|
||||||
|
|
||||||
|
if (desc == null)
|
||||||
|
desc = resultSetDescriptorFactory.newInstance();
|
||||||
|
|
||||||
|
final List<String> res = new ArrayList<String>();
|
||||||
|
|
||||||
|
log.debug("ranges containing " + fromPosition + " to " + toPosition);
|
||||||
|
for (final Range range : desc.getRangesContaining(fromPosition, toPosition)) {
|
||||||
|
log.debug("reading range " + key + "-" + range.getRange() + " begin: " + range.getBegin() + " end: " + range.getEnd());
|
||||||
|
res.addAll(cache.get(key + "-" + range.getRange()).subList(range.getBegin(), range.getEnd()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, List<String>> getCache() {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setCache(final Cache<String, List<String>> cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, ResultSetDescriptor> getResultSetCache() {
|
||||||
|
return resultSetCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setResultSetCache(final Cache<String, ResultSetDescriptor> resultSetCache) {
|
||||||
|
this.resultSetCache = resultSetCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Factory<ResultSetDescriptor> getResultSetDescriptorFactory() {
|
||||||
|
return resultSetDescriptorFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSetDescriptorFactory(final Factory<ResultSetDescriptor> resultSetDescriptorFactory) {
|
||||||
|
this.resultSetDescriptorFactory = resultSetDescriptorFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset which receive data through the "push" interface, i.e. data is directly appended to it.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface PushResultSet extends ResultSet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a list of elements at the end of the resultset.
|
||||||
|
*
|
||||||
|
* @param elements list of elements
|
||||||
|
*/
|
||||||
|
void addElements(List<String> elements);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a new push resultset.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface PushResultSetFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new push resultset.
|
||||||
|
*
|
||||||
|
* @param maxIdleTime max time the resultset can be idle
|
||||||
|
* @return push resultset epr
|
||||||
|
*/
|
||||||
|
W3CEndpointReference createPushResultSet(int maxIdleTime);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a push resultset.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* A push resultset stores it's data in several ranges
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResultSetDescriptor implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(Range.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class describes a range.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Range {
|
||||||
|
private int range;
|
||||||
|
private int begin;
|
||||||
|
private int end;
|
||||||
|
|
||||||
|
public Range(final int range, final int begin, final int end) {
|
||||||
|
super();
|
||||||
|
this.range = range;
|
||||||
|
this.begin = begin;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Range(" + range + ", " + begin + ", " + end + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRange() {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRange(final int range) {
|
||||||
|
this.range = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBegin() {
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBegin(final int begin) {
|
||||||
|
this.begin = begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEnd() {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnd(final int end) {
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 7699992350256317181L;
|
||||||
|
|
||||||
|
private int rangeLength = 100;
|
||||||
|
|
||||||
|
private int ranges = 0;
|
||||||
|
|
||||||
|
public int getLastRange() {
|
||||||
|
return ranges - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fromPosition
|
||||||
|
* 1 based count
|
||||||
|
* @param toPosition
|
||||||
|
* 1 based count
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Iterable<Range> getRangesContaining(final int fromPosition, final int toPosition) {
|
||||||
|
|
||||||
|
final int fromRange = (fromPosition - 1) / rangeLength;
|
||||||
|
int ttoRange = (int) Math.ceil((toPosition * 1.0) / rangeLength);
|
||||||
|
|
||||||
|
if (ttoRange > ranges)
|
||||||
|
ttoRange = ranges;
|
||||||
|
|
||||||
|
final int toRange = ttoRange;
|
||||||
|
|
||||||
|
log.debug("FROM range: " + fromRange);
|
||||||
|
log.debug("TTO range: " + ttoRange);
|
||||||
|
log.debug("TO range: " + toRange);
|
||||||
|
|
||||||
|
return new Iterable<Range>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Range> iterator() {
|
||||||
|
return new Iterator<Range>() {
|
||||||
|
|
||||||
|
int current = fromRange;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return current < toRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Range next() {
|
||||||
|
int begin = 0;
|
||||||
|
int end = rangeLength;
|
||||||
|
if (current == fromRange)
|
||||||
|
begin = (fromPosition - 1) % rangeLength;
|
||||||
|
if ((current + 1) == toRange)
|
||||||
|
end = (toPosition - 1) % rangeLength + 1;
|
||||||
|
return new Range(current++, begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new IllegalStateException("text");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRangeLength() {
|
||||||
|
return rangeLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRangeLength(final int rangeLength) {
|
||||||
|
this.rangeLength = rangeLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRanges() {
|
||||||
|
return ranges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRanges(final int ranges) {
|
||||||
|
this.ranges = ranges;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.factory.Factory;
|
||||||
|
|
||||||
|
public interface ResultSetDescriptorFactory extends Factory<ResultSetDescriptor> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* offer access to the underlying in-memory or pseudo-memory (serialization backed caches) storage for the transient
|
||||||
|
* push-resultsets.
|
||||||
|
*
|
||||||
|
* This type of push resultsets doesn't even try to make efficient access to records, they just keep them as big lists
|
||||||
|
* on the underlying storage. Actual implementations may decide to keep them on the heap or to use some caching
|
||||||
|
* technology like ehcache.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface TransientPushResultSetDao {
|
||||||
|
/**
|
||||||
|
* add elements to a given key.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* usually a rsid.
|
||||||
|
* @param elements
|
||||||
|
* list of elements
|
||||||
|
*/
|
||||||
|
void addElements(String key, List<String> elements);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obtain content for a given key (resultset) in a given range (1 based).
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* usually a rsid
|
||||||
|
* @param fromPosition from position (1 based, inclusive)
|
||||||
|
* @param toPosition to position (1 based, inclusive)
|
||||||
|
* @return all the elements for a given key
|
||||||
|
*/
|
||||||
|
List<String> getElements(String key, int fromPosition, int toPosition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the resultset size (number of elements).
|
||||||
|
*
|
||||||
|
* @param key usually a rsid
|
||||||
|
* @return resultset size
|
||||||
|
*/
|
||||||
|
int getSize(String key);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a transient push resultset.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TransientPushResultSetFactory extends AbstractPushResultSetFactoryImpl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dao.
|
||||||
|
*/
|
||||||
|
private TransientPushResultSetDao dao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.AbstractPushResultSetFactoryImpl#newInstance()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected PushResultSet newInstance() {
|
||||||
|
return new TransientPushResultSetImpl(dao);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransientPushResultSetDao getDao() {
|
||||||
|
return dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDao(final TransientPushResultSetDao dao) {
|
||||||
|
this.dao = dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.AbstractObservableResultset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a push resultset which holds it's data in a transient cache.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TransientPushResultSetImpl extends AbstractObservableResultset implements PushResultSet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(TransientPushResultSetImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dao.
|
||||||
|
*/
|
||||||
|
private final transient TransientPushResultSetDao dao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsId.
|
||||||
|
*/
|
||||||
|
private String identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructed by the transient push resultset factory.
|
||||||
|
*
|
||||||
|
* @param dao dao
|
||||||
|
*/
|
||||||
|
public TransientPushResultSetImpl(final TransientPushResultSetDao dao) {
|
||||||
|
super();
|
||||||
|
this.dao = dao;
|
||||||
|
setOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.PushResultSet#addElements(java.util.List)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addElements(final List<String> elements) {
|
||||||
|
log.debug("adding to push RS: " + elements);
|
||||||
|
|
||||||
|
if (isOpen())
|
||||||
|
dao.addElements(getIdentifier(), elements);
|
||||||
|
else
|
||||||
|
throw new IllegalStateException("cannot write to a closed push resultset");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfResults() {
|
||||||
|
return dao.getSize(getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSet#getResults(int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResults(final int fromPosition, final int toPosition) {
|
||||||
|
|
||||||
|
final int size = getNumberOfResults();
|
||||||
|
int toPos = toPosition;
|
||||||
|
int fromPos = fromPosition;
|
||||||
|
if (fromPos > size)
|
||||||
|
fromPos = size;
|
||||||
|
if (toPos > size)
|
||||||
|
toPos = size;
|
||||||
|
|
||||||
|
log.debug("calling get elements: " + getIdentifier() + " from " + fromPos + " to " + toPos);
|
||||||
|
return dao.getElements(getIdentifier(), fromPos, toPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransientPushResultSetDao getDao() {
|
||||||
|
return dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIdentifier(final String identifier) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
xmlns:util="http://www.springframework.org/schema/util" xmlns:template="http://dnetlib.eu/springbeans/template"
|
||||||
|
xmlns:t="http://dnetlib.eu/springbeans/t"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||||
|
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
|
||||||
|
http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd
|
||||||
|
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||||
|
|
||||||
|
<!-- beans -->
|
||||||
|
|
||||||
|
<bean id="hcmService"
|
||||||
|
class="eu.dnetlib.enabling.hcm.HostingContextManagerServiceImpl"
|
||||||
|
init-method="start" destroy-method="stop"
|
||||||
|
p:notificationHandler-ref="hcmNotificationHandler"/>
|
||||||
|
|
||||||
|
<bean id="hcmNotificationHandler" class="eu.dnetlib.enabling.tools.blackboard.NotificationHandlerChainImpl"
|
||||||
|
p:handlers-ref="dynamicSubscriptionActions">
|
||||||
|
<property name="handlerExecutor">
|
||||||
|
<bean class="org.springframework.core.task.SyncTaskExecutor" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="dynamicSubscriptionActions"
|
||||||
|
class="eu.dnetlib.enabling.hcm.sn.HCMSubscriptionListFactory" />
|
||||||
|
|
||||||
|
<bean id="hcmSubscriber" class="eu.dnetlib.enabling.hcm.sn.HCMSubscriberImpl"
|
||||||
|
p:endpoint-ref="hcmServiceEndpoint" p:serviceLocator-ref="uniqueServiceLocator"
|
||||||
|
p:actions-ref="dynamicSubscriptionActions" />
|
||||||
|
|
||||||
|
<bean t:id="hcmJobSchedulerAccessor"
|
||||||
|
class="org.springframework.scheduling.quartz.SchedulerAccessorBean"
|
||||||
|
p:scheduler-ref="jobScheduler">
|
||||||
|
<property name="triggers">
|
||||||
|
<list>
|
||||||
|
<bean id="hcmSubscriptionTrigger"
|
||||||
|
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
|
||||||
|
p:startDelay="6000" p:repeatCount="0">
|
||||||
|
<property name="jobDetail">
|
||||||
|
<bean id="hcmSubscriptionJobDetails"
|
||||||
|
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
|
||||||
|
p:targetObject-ref="hcmSubscriber" p:targetMethod="subscribeAll" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- endpoints -->
|
||||||
|
<jaxws:endpoint id="hcmServiceEndpoint" implementor="#hcmService"
|
||||||
|
implementorClass="eu.dnetlib.enabling.hcm.rmi.HostingContextManagerService"
|
||||||
|
address="/hcm" />
|
||||||
|
|
||||||
|
<template:instance name="serviceRegistrationManager"
|
||||||
|
t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
|
||||||
|
t:name="hcmServiceRegistrationManager" t:service="hcmService"
|
||||||
|
t:endpoint="hcmServiceEndpoint" t:jobScheduler="jobScheduler" />
|
||||||
|
</beans>
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
|
||||||
|
xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:wsa="http://cxf.apache.org/ws/addressing"
|
||||||
|
xmlns:p="http://www.springframework.org/schema/p" xmlns:http="http://cxf.apache.org/transports/http/configuration"
|
||||||
|
xmlns:t="http://dnetlib.eu/springbeans/t" xmlns:template="http://dnetlib.eu/springbeans/template"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schemas/ws-addr-conf.xsd
|
||||||
|
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
|
||||||
|
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
|
||||||
|
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
|
||||||
|
http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd">
|
||||||
|
|
||||||
|
<!-- beans -->
|
||||||
|
<bean id="hnmService" class="eu.dnetlib.enabling.hnm.HostingNodeManagerServiceImpl"
|
||||||
|
init-method="start" destroy-method="stop"/>
|
||||||
|
|
||||||
|
<!-- endpoints -->
|
||||||
|
<jaxws:endpoint id="hnmServiceEndpoint"
|
||||||
|
implementor="#hnmService" implementorClass="eu.dnetlib.enabling.hnm.rmi.HostingNodeManagerService"
|
||||||
|
address="/hnm" />
|
||||||
|
|
||||||
|
<template:instance name="serviceRegistrationManager"
|
||||||
|
t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
|
||||||
|
t:name="hnmServiceRegistrationManager" t:service="hnmService"
|
||||||
|
t:endpoint="hnmServiceEndpoint" t:jobScheduler="jobScheduler"
|
||||||
|
t:serviceRegistrator="hnmServiceRegistrator" />
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="hnmServiceRegistrator"
|
||||||
|
class="eu.dnetlib.enabling.tools.registration.BlackboardServiceRegistrator"
|
||||||
|
p:serviceLocator-ref="uniqueServiceLocator"
|
||||||
|
p:serviceNameResolver-ref="defaultServiceNameResolver"
|
||||||
|
p:eprBuilder-ref="jaxwsEndpointReferenceBuilder">
|
||||||
|
<property name="serviceProperties">
|
||||||
|
<map>
|
||||||
|
<entry key="name" value="unknown" />
|
||||||
|
<entry key="latitude" value="0" />
|
||||||
|
<entry key="longitude" value="0" />
|
||||||
|
<entry key="timezone" value="0" />
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,10 @@
|
||||||
|
services.is.resultset.resultSetRegistryCache.timeToIdle = 240
|
||||||
|
services.is.resultset.resultSetRegistryMaxIdleTimeCache.timeToIdle = 240
|
||||||
|
|
||||||
|
# jaxwsEndpointReferenceBuilder | staticResultSetServiceEprBuilder
|
||||||
|
services.resultset.eprbuilder.bean = jaxwsEndpointReferenceBuilder
|
||||||
|
services.resultset.endpoint.static.address = ${transport.soap.baseAddress}/resultSet
|
||||||
|
|
||||||
|
services.is.resultset.push.timeToIdle=36000
|
||||||
|
services.is.resultset.push.maxElementsInMemory=500
|
||||||
|
services.is.resultset.push.maxElementsOnDisk=5000000
|
|
@ -0,0 +1,138 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
|
||||||
|
xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:wsa="http://cxf.apache.org/ws/addressing"
|
||||||
|
xmlns:p="http://www.springframework.org/schema/p" xmlns:http="http://cxf.apache.org/transports/http/configuration"
|
||||||
|
xmlns:t="http://dnetlib.eu/springbeans/t" xmlns:template="http://dnetlib.eu/springbeans/template"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schemas/ws-addr-conf.xsd
|
||||||
|
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
|
||||||
|
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
|
||||||
|
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
|
||||||
|
http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd">
|
||||||
|
|
||||||
|
<!-- beans -->
|
||||||
|
<bean id="resultSetCacheManager"
|
||||||
|
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
|
||||||
|
<!-- p:configLocation="classpath:eu/dnetlib/enabling/resultset/ehcache.xml" -->
|
||||||
|
|
||||||
|
<bean id="resultSetRegistryCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||||
|
<property name="cache">
|
||||||
|
<bean id="resultSetRegistryCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||||
|
p:cacheManager-ref="resultSetCacheManager" p:cacheName="resultSetFactoryCache"
|
||||||
|
p:eternal="false" p:timeToLive="${services.is.resultset.resultSetRegistryCache.timeToIdle}"
|
||||||
|
p:timeToIdle="${services.is.resultset.resultSetRegistryCache.timeToIdle}" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="resultSetRegistryMaxIdleTimeCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||||
|
<property name="cache">
|
||||||
|
<bean id="resultSetRegistryMaxIdleTimeCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||||
|
p:cacheManager-ref="resultSetCacheManager" p:cacheName="resultSetFactoryMaxIdleTimeCache"
|
||||||
|
p:eternal="false" p:timeToLive="${services.is.resultset.resultSetRegistryMaxIdleTimeCache.timeToIdle}"
|
||||||
|
p:timeToIdle="${services.is.resultset.resultSetRegistryMaxIdleTimeCache.timeToIdle}" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- backing store for the pushResultSetDao -->
|
||||||
|
<bean id="pushResultSetStoreCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||||
|
<property name="cache">
|
||||||
|
<bean id="pushResultSetStoreCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||||
|
p:eternal="false" p:timeToLive="${services.is.resultset.push.timeToIdle}" p:timeToIdle="${services.is.resultset.push.timeToIdle}"
|
||||||
|
p:overflowToDisk="true"
|
||||||
|
p:maxElementsInMemory="${services.is.resultset.push.maxElementsInMemory}"
|
||||||
|
p:maxElementsOnDisk="${services.is.resultset.push.maxElementsOnDisk}"
|
||||||
|
p:cacheManager-ref="resultSetCacheManager" p:cacheName="pushResultSetStoreCache" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- resultset descriptor store for the pushResultSetDao -->
|
||||||
|
<bean id="pushResultSetDescriptorCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||||
|
<property name="cache">
|
||||||
|
<bean id="pushResultSetDescriptorCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||||
|
p:eternal="false" p:timeToLive="1800" p:timeToIdle="1800"
|
||||||
|
p:cacheManager-ref="resultSetCacheManager" p:cacheName="pushResultSetDescriptorCache" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="resultSetDescriptorFactory" class="eu.dnetlib.springutils.beans.factory.PrototypeFactory">
|
||||||
|
<lookup-method name="newInstance" bean="resultSetDescriptorPrototype" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="resultSetDescriptorPrototype" class="eu.dnetlib.enabling.resultset.push.ResultSetDescriptor"
|
||||||
|
p:rangeLength="100" scope="prototype" />
|
||||||
|
|
||||||
|
<bean id="resultSetRegistry" class="eu.dnetlib.enabling.resultset.ResultSetRegistryImpl"
|
||||||
|
p:cache-ref="resultSetRegistryCache" p:maxIdleTimeCache-ref="resultSetRegistryMaxIdleTimeCache" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<bean id="resultSetEPRPool" class="eu.dnetlib.enabling.resultset.ResultSetEPRPool"
|
||||||
|
p:resultSetService-ref="resultSetService" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- <bean id="resultSetFactory" class="eu.dnetlib.enabling.resultset.LocalResultSetFactoryImpl" -->
|
||||||
|
<!-- <bean id="resultSetFactory" class="eu.dnetlib.enabling.resultset.EPRPoolingLocalResultSetFactoryImpl" p:pool-ref="resultSetEPRPool"
|
||||||
|
p:resultSetService-ref="resultSetService" /> -->
|
||||||
|
|
||||||
|
<bean id="resultSetFactory" class="eu.dnetlib.enabling.resultset.LocalResultSetFactoryImpl"
|
||||||
|
p:resultSetService-ref="resultSetService" />
|
||||||
|
|
||||||
|
<bean id="openResultSetFactory"
|
||||||
|
class="eu.dnetlib.enabling.resultset.LocalOpenResultSetFactoryImpl"
|
||||||
|
p:resultSetService-ref="resultSetService" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<bean id="openResultSetFactory"
|
||||||
|
class="eu.dnetlib.enabling.resultset.EPRPoolingLocalOpenResultSetFactoryImpl" p:pool-ref="resultSetEPRPool"
|
||||||
|
p:resultSetService-ref="resultSetService" />
|
||||||
|
-->
|
||||||
|
<bean id="mappedResultSetFactory" class="eu.dnetlib.enabling.resultset.MappedResultSetFactory"
|
||||||
|
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||||
|
|
||||||
|
<bean id="parallelMappedResultSetFactory" class="eu.dnetlib.enabling.resultset.ParallelMappedResultSetFactory"
|
||||||
|
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||||
|
|
||||||
|
<bean id="xsltResultSetFactory"
|
||||||
|
class="eu.dnetlib.enabling.resultset.XSLTMappedResultSetFactory"
|
||||||
|
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||||
|
|
||||||
|
<bean id="countingResultSetFactory" class="eu.dnetlib.enabling.resultset.CountingResultSetFactory"
|
||||||
|
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||||
|
|
||||||
|
<bean id="streamingResultSetFactory" class="eu.dnetlib.enabling.resultset.StreamingResultSetFactory"
|
||||||
|
p:resultSetFactory-ref="resultSetFactory" />
|
||||||
|
|
||||||
|
<bean id="cachingResultSetFactory" class="eu.dnetlib.enabling.resultset.CachingResultSetFactory"
|
||||||
|
p:resultSetFactory-ref="resultSetFactory" />
|
||||||
|
|
||||||
|
<bean id="pushResultSetFactory"
|
||||||
|
class="eu.dnetlib.enabling.resultset.push.TransientPushResultSetFactory"
|
||||||
|
p:dao-ref="pushResultSetDao" p:resultSetService-ref="resultSetService" />
|
||||||
|
|
||||||
|
<bean id="iterableResultSetFactory" class="eu.dnetlib.enabling.resultset.IterableResultSetFactory"
|
||||||
|
p:fetchSize="10" p:resultSetFactory-ref="openResultSetFactory"
|
||||||
|
lazy-init="true" />
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="pushResultSetDao"
|
||||||
|
class="eu.dnetlib.enabling.resultset.push.CacheTransientResultSetDaoImpl"
|
||||||
|
p:cache-ref="pushResultSetStoreCache" p:resultSetCache-ref="pushResultSetDescriptorCache" />
|
||||||
|
|
||||||
|
<bean id="customResultSetPropertyDao" class="eu.dnetlib.enabling.resultset.ResultSetPropertyDaoImpl" />
|
||||||
|
|
||||||
|
<bean id="resultSetService" class="eu.dnetlib.enabling.resultset.ResultSetServiceImpl"
|
||||||
|
init-method="start" p:resultsetRegistry-ref="resultSetRegistry"
|
||||||
|
p:pushFactory-ref="pushResultSetFactory" p:endpoint-ref="resultSetServiceEndpoint"
|
||||||
|
p:eprBuilder-ref="jaxwsEndpointReferenceBuilder" p:customPropertyDao-ref="customResultSetPropertyDao" />
|
||||||
|
|
||||||
|
<!-- endpoints -->
|
||||||
|
<jaxws:endpoint id="resultSetServiceEndpoint"
|
||||||
|
implementor="#resultSetService" implementorClass="eu.dnetlib.enabling.resultset.rmi.ResultSetService"
|
||||||
|
address="/resultSet" />
|
||||||
|
|
||||||
|
<template:instance name="serviceRegistrationManager"
|
||||||
|
t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
|
||||||
|
t:name="resultSetServiceRegistrationManager" t:service="resultSetService"
|
||||||
|
t:endpoint="resultSetServiceEndpoint" t:jobScheduler="jobScheduler" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,75 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class FetchListTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* object to test
|
||||||
|
*/
|
||||||
|
private FetchList<String> fetchList;
|
||||||
|
|
||||||
|
private List<String> list;
|
||||||
|
private Iterator<String> iter;
|
||||||
|
|
||||||
|
private int FETCH_SIZE = 10;
|
||||||
|
|
||||||
|
private int TOTAL_ELEMENTS = 100;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
list = new ArrayList<String>();
|
||||||
|
for (int i = 0; i < TOTAL_ELEMENTS; i++) {
|
||||||
|
list.add("XXX" + i);
|
||||||
|
}
|
||||||
|
this.iter = list.iterator();
|
||||||
|
fetchList = new FetchList<String>(iter, FETCH_SIZE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFetchList() {
|
||||||
|
assertNotNull(fetchList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPoll_consumedElements() {
|
||||||
|
assertEquals(0, fetchList.getConsumedElements());
|
||||||
|
fetchList.poll();
|
||||||
|
assertEquals(1, fetchList.getConsumedElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFill_totalElements() {
|
||||||
|
assertEquals(FETCH_SIZE, fetchList.getTotalElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPoll() {
|
||||||
|
for (int i = 0; i < TOTAL_ELEMENTS; i++) {
|
||||||
|
assertEquals(i, fetchList.getConsumedElements());
|
||||||
|
assertEquals(list.get(i), fetchList.poll());
|
||||||
|
}
|
||||||
|
assertEquals(TOTAL_ELEMENTS, fetchList.getConsumedElements());
|
||||||
|
assertEquals(TOTAL_ELEMENTS, fetchList.getTotalElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPoll_null() {
|
||||||
|
for (int i = 0; i < TOTAL_ELEMENTS; i++) {
|
||||||
|
fetchList.poll();
|
||||||
|
}
|
||||||
|
assertNull(fetchList.poll());
|
||||||
|
assertNull(fetchList.poll());
|
||||||
|
assertNull(fetchList.poll());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests the IterableResult class
|
||||||
|
*
|
||||||
|
* @author claudio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class IterableResultSetTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of total elements
|
||||||
|
*/
|
||||||
|
private static int NUM_ELEM = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of elements available to fetch
|
||||||
|
*/
|
||||||
|
private static int FETCH_SIZE = 10;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ResultSet mockResultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a list used to compare elements.
|
||||||
|
*/
|
||||||
|
private List<String> list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator associated with the test list.
|
||||||
|
*/
|
||||||
|
private Iterator<String> iter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object to test.
|
||||||
|
*/
|
||||||
|
private IterableResultSet iterResultSet;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
list = new ArrayList<String>();
|
||||||
|
for (int i=0; i< NUM_ELEM; i++)
|
||||||
|
list.add("XXXXX " + i);
|
||||||
|
|
||||||
|
iter = list.iterator();
|
||||||
|
when(mockResultSet.isOpen()).thenReturn(iter.hasNext());
|
||||||
|
|
||||||
|
iterResultSet = new IterableResultSet(list, FETCH_SIZE);
|
||||||
|
iterResultSet.setResultSet(mockResultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIterableResultSet() {
|
||||||
|
assertNotNull(iterResultSet);
|
||||||
|
assertTrue(iterResultSet.getSize() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=RuntimeException.class)
|
||||||
|
public void testGetResult_fail_1() {
|
||||||
|
iterResultSet.getResult(0, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=RuntimeException.class)
|
||||||
|
public void testGetResult_fail_2() {
|
||||||
|
iterResultSet.getResult(1, 5);
|
||||||
|
iterResultSet.getResult(1, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=RuntimeException.class)
|
||||||
|
public void testGetResult_fail_3() {
|
||||||
|
iterResultSet.getResult(1, 5);
|
||||||
|
iterResultSet.getResult(6, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=RuntimeException.class)
|
||||||
|
public void testGetResult_fail_4() {
|
||||||
|
iterResultSet.getResult(1, 5);
|
||||||
|
iterResultSet.getResult(7, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult_success_1() {
|
||||||
|
List<String> result = iterResultSet.getResult(1, NUM_ELEM);
|
||||||
|
for (int i=0; i<NUM_ELEM; i++) {
|
||||||
|
assertEquals(list.get(i), result.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult_success_2() {
|
||||||
|
List<String> result = iterResultSet.getResult(1, NUM_ELEM);
|
||||||
|
|
||||||
|
for (int i=0; i<NUM_ELEM; i++) {
|
||||||
|
assertEquals(list.get(i), result.get(i));
|
||||||
|
iter.next();
|
||||||
|
}
|
||||||
|
verify(mockResultSet).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult_success_3() {
|
||||||
|
for (int i = 1; i < NUM_ELEM; i+= FETCH_SIZE)
|
||||||
|
iterResultSet.getResult(i, i + FETCH_SIZE-1);
|
||||||
|
verify(mockResultSet, times(1)).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult_success_4() {
|
||||||
|
iterResultSet.getResult(1, NUM_ELEM + 1);
|
||||||
|
verify(mockResultSet, times(1)).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResultSet_success_1() {
|
||||||
|
assertNotNull(iterResultSet.getResultSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSize_fail_1() {
|
||||||
|
iterResultSet.getResult(1, 8);
|
||||||
|
assertNotSame(7, iterResultSet.getSize());
|
||||||
|
assertNotSame(9, iterResultSet.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSize_success_1() {
|
||||||
|
iterResultSet.getResult(1, 8);
|
||||||
|
assertEquals(FETCH_SIZE, iterResultSet.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*; // NOPMD
|
||||||
|
import static org.mockito.Mockito.*; // NOPMD by marko on 11/26/08 9:13 PM
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test the resultset concrete implementation.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class LocalResultSetImplTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class could be an anonymous class, but is here to be shared among tests.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final class TestResultSetListener implements ResultSetListener {
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.ResultSetListener#getResult(int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getResult(final int fromPosition, final int toPosition) {
|
||||||
|
final List<String> res = new ArrayList<String>();
|
||||||
|
for (int i = fromPosition; i <= toPosition; i++)
|
||||||
|
res.add(((Integer) (i - 1)).toString());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return RESULT_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mockito lacks of multiple interfaces mocking.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private abstract static class AbstractResultSetAware implements ResultSetListener, ResultSetAware {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset registry mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetRegistry registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* object under test.
|
||||||
|
*/
|
||||||
|
private transient LocalResultSetImpl resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of returned test results.
|
||||||
|
*/
|
||||||
|
private static final int RESULT_SIZE = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provides data to the resultset under test.
|
||||||
|
*/
|
||||||
|
private transient TestResultSetListener resultSetListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prepare.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
resultSetListener = new TestResultSetListener();
|
||||||
|
resultSet = new LocalResultSetImpl(resultSetListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test the get number of results method.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetNumberOfResults() {
|
||||||
|
assertEquals("check number of results", RESULT_SIZE, resultSet.getNumberOfResults());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test the get result method.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetResults() {
|
||||||
|
final List<String> res = resultSet.getResults(1, RESULT_SIZE); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("whole length", RESULT_SIZE, res.size());
|
||||||
|
for (int i = 0; i < RESULT_SIZE; i++)
|
||||||
|
assertEquals("check element", ((Integer) i).toString(), res.get(i));
|
||||||
|
|
||||||
|
final List<String> res2 = resultSet.getResults(1, RESULT_SIZE - 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("shorter", RESULT_SIZE - 1, res2.size());
|
||||||
|
|
||||||
|
final List<String> res3 = resultSet.getResults(1, RESULT_SIZE + 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("to out of bounds", RESULT_SIZE, res3.size());
|
||||||
|
|
||||||
|
final List<String> res4 = resultSet.getResults(RESULT_SIZE + 1, RESULT_SIZE); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("from out of bounds", 0, res4.size());
|
||||||
|
|
||||||
|
final List<String> res5 = resultSet.getResults(0, RESULT_SIZE); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("from lesser than 1", RESULT_SIZE, res5.size());
|
||||||
|
|
||||||
|
final List<String> res6 = resultSet.getResults(RESULT_SIZE, 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("inverted from and to", 1, res6.size());
|
||||||
|
|
||||||
|
resultSet.setOpen(true);
|
||||||
|
final List<String> res7 = resultSet.getResults(1, RESULT_SIZE + 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||||
|
assertEquals("to out of bounds - pass through", RESULT_SIZE + 1, res7.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test observer/observable pattern.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDestroy() {
|
||||||
|
resultSet.addObserver(registry);
|
||||||
|
assertEquals("observer should be added", 1, resultSet.countObservers());
|
||||||
|
|
||||||
|
resultSet.destroy();
|
||||||
|
assertTrue("should be destroyed", resultSet.isDestroyed());
|
||||||
|
|
||||||
|
assertEquals("observers should be cleared", 0, resultSet.countObservers());
|
||||||
|
verify(registry, times(1)).update(resultSet, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test getter ... let's make code coverage happy.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetListener() {
|
||||||
|
assertEquals("test getter?", resultSetListener, resultSet.getListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test setter ... let's make code coverage happy.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSetListener() {
|
||||||
|
assertEquals("test getter?", resultSetListener, resultSet.getListener());
|
||||||
|
resultSet.setListener(null);
|
||||||
|
assertNull("test setter?", resultSet.getListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testResultSetAware() {
|
||||||
|
final AbstractResultSetAware abr = mock(AbstractResultSetAware.class);
|
||||||
|
resultSet = new LocalResultSetImpl(abr);
|
||||||
|
assertNotNull("dummy", resultSet);
|
||||||
|
|
||||||
|
verify(abr).setResultSet((ResultSet) anyObject());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package eu.dnetlib.enabling.resultset; // NOPMD
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Matchers.anyObject;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
import eu.dnetlib.miscutils.factory.Factory;
|
||||||
|
import eu.dnetlib.miscutils.functional.ThreadSafeUnaryFunction;
|
||||||
|
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test xslt resultset.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class MappedResultSetTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instance under test.
|
||||||
|
*/
|
||||||
|
private transient MappedResultSet mappedResultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* service resolver.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ServiceResolver serviceResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset service mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetService resultSetService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSet resultSet;
|
||||||
|
|
||||||
|
private Answer<Object> resultSetAnswer = new Answer<Object>() {
|
||||||
|
|
||||||
|
private List<String> list = Lists.newArrayList("1","2","3","4","5","6","7","8","9","10");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||||
|
String method = invocation.getMethod().getName();
|
||||||
|
if (method.equals("getResult") || method.equals("getResults")) {
|
||||||
|
int from = (Integer) invocation.getArguments()[1];
|
||||||
|
int to = (Integer) invocation.getArguments()[2];
|
||||||
|
|
||||||
|
return list.subList(from-1, to);
|
||||||
|
}
|
||||||
|
if (method.equals("getNumberOfElements") || method.equals("getNumberOfResults")) {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
if (method.equals("getRSStatus")) {
|
||||||
|
return "closed";
|
||||||
|
}
|
||||||
|
if (method.equals("isOpen")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
System.out.println(invocation.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common setup.
|
||||||
|
* @throws ResultSetException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() throws ResultSetException {
|
||||||
|
|
||||||
|
when(serviceResolver.getService(eq(ResultSetService.class), any(W3CEndpointReference.class))).thenReturn(resultSetService);
|
||||||
|
when(serviceResolver.getResourceIdentifier(any(W3CEndpointReference.class))).thenReturn("123");
|
||||||
|
|
||||||
|
when(resultSetService.getNumberOfElements(anyString())).thenAnswer(resultSetAnswer);
|
||||||
|
when(resultSetService.getResult(anyString(), anyInt(), anyInt(), anyString())).thenAnswer(resultSetAnswer );
|
||||||
|
when(resultSetService.getRSStatus(anyString())).thenAnswer(resultSetAnswer);
|
||||||
|
|
||||||
|
when(resultSet.getNumberOfResults()).thenAnswer(resultSetAnswer);
|
||||||
|
when(resultSet.getResults(anyInt(), anyInt())).thenAnswer(resultSetAnswer );
|
||||||
|
when(resultSet.isOpen()).thenAnswer(resultSetAnswer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testThreadSafeMappedResultSet_1() {
|
||||||
|
|
||||||
|
final Factory<UnaryFunction<String, String>> functionFactory = new Factory<UnaryFunction<String,String>>() {
|
||||||
|
@Override
|
||||||
|
public UnaryFunction<String, String> newInstance() {
|
||||||
|
return new UnaryFunction<String, String>() {
|
||||||
|
@Override
|
||||||
|
public String evaluate(String arg) {
|
||||||
|
return "mapped-" + arg;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mappedResultSet = new MappedResultSet(null, new ThreadSafeUnaryFunction<String, String>(functionFactory), serviceResolver);
|
||||||
|
mappedResultSet.setResultSet(resultSet);
|
||||||
|
|
||||||
|
for (String s : mappedResultSet.getResult(1, 10)) {
|
||||||
|
assertNotNull("null result", s);
|
||||||
|
assertFalse("empty result", s.isEmpty());
|
||||||
|
assertNotNull("null element", s);
|
||||||
|
assertTrue("transformed correctly", s.startsWith("mapped-"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.matches;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
import net.sf.ehcache.CacheManager;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.cache.EhCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test ResultSetRegistryImpl.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ResultSetRegistryImplTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* max in memory elements.
|
||||||
|
*/
|
||||||
|
private static final int MAX_IN_MEM = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default time.
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_TTI = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default time to live.
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_TTL = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class under test.
|
||||||
|
*/
|
||||||
|
private transient ResultSetRegistryImpl registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mock of a resultset object.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSet resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ehcache manager.
|
||||||
|
*/
|
||||||
|
private final transient CacheManager cacheManager = CacheManager.create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up basic mocks.
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
final Cache ehCache = new net.sf.ehcache.Cache("testCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||||
|
cacheManager.addCache(ehCache);
|
||||||
|
|
||||||
|
final Cache mtEhCache = new net.sf.ehcache.Cache("testMTCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||||
|
cacheManager.addCache(mtEhCache);
|
||||||
|
|
||||||
|
final EhCache<String, ResultSet> cache = new EhCache<String, ResultSet>(ehCache);
|
||||||
|
cache.setCache(ehCache);
|
||||||
|
|
||||||
|
final EhCache<String, Integer> mtCache = new EhCache<String, Integer>(mtEhCache);
|
||||||
|
mtCache.setCache(mtEhCache);
|
||||||
|
|
||||||
|
registry = new ResultSetRegistryImpl();
|
||||||
|
registry.setCache(cache);
|
||||||
|
registry.setMaxIdleTimeCache(mtCache);
|
||||||
|
|
||||||
|
when(resultSet.getIdentifier()).thenReturn("123456");
|
||||||
|
when(resultSet.isOpen()).thenReturn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove ehcache from ehcachemanager.
|
||||||
|
*/
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
cacheManager.removeAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that registered resultsets are really registered.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddResultSet() {
|
||||||
|
|
||||||
|
final String rsId = resultSet.getIdentifier();
|
||||||
|
assertNotNull("the resultset should not be null", rsId);
|
||||||
|
|
||||||
|
registry.addResultSet(resultSet);
|
||||||
|
verify(resultSet).setIdentifier(matches("rs-" + registry.getIdGenerator().getRegEx()));
|
||||||
|
|
||||||
|
final ResultSet res = registry.getResultSetById(rsId); // NOPMD
|
||||||
|
assertNotNull("the resultset is not found", res);
|
||||||
|
assertEquals("the resultsets don't have the same id", rsId, res.getIdentifier());
|
||||||
|
assertEquals("the resultsets are not the same instance", resultSet, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that registered resultsets are really registered.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddResultSetWithId() {
|
||||||
|
resultSet = mock(ResultSet.class);
|
||||||
|
when(resultSet.getIdentifier()).thenReturn("123");
|
||||||
|
|
||||||
|
final String rsId = resultSet.getIdentifier();
|
||||||
|
|
||||||
|
registry.addResultSet(resultSet, rsId);
|
||||||
|
verify(resultSet).setIdentifier(rsId);
|
||||||
|
|
||||||
|
final ResultSet res = registry.getResultSetById(rsId); // NOPMD
|
||||||
|
assertNotNull("the resultset is not found", res);
|
||||||
|
assertEquals("the resultsets don't have the same id", rsId, res.getIdentifier());
|
||||||
|
assertEquals("the resultsets are not the same instance", resultSet, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try to obtain a inexistent resultset.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testInexistentResultSet() {
|
||||||
|
final String rsId = resultSet.getIdentifier();
|
||||||
|
assertNull("inexisten resultset returns null", registry.getResultSetById(rsId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test closing of resultset and its pruning from the registry.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testResultSetClose() {
|
||||||
|
final String rsId = resultSet.getIdentifier();
|
||||||
|
|
||||||
|
assertTrue("check if resultset is open", resultSet.isOpen());
|
||||||
|
|
||||||
|
registry.addResultSet(resultSet);
|
||||||
|
verify(resultSet).addObserver(registry);
|
||||||
|
|
||||||
|
// simulate a resultset close on the mock
|
||||||
|
when(resultSet.isOpen()).thenReturn(false);
|
||||||
|
registry.update(resultSet, null);
|
||||||
|
|
||||||
|
assertFalse("check if resultset is closed", resultSet.isOpen());
|
||||||
|
assertNull("check if the object is pruned from the registry", registry.getResultSetById(rsId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* same as testResultSetClose() but with a real observer/observable mechanism, i.e. without resultset mock class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithRealObservable() {
|
||||||
|
final LocalResultSetImpl rset = new LocalResultSetImpl(null);
|
||||||
|
rset.setIdentifier("123456");
|
||||||
|
resultSet = rset;
|
||||||
|
|
||||||
|
final String rsId = resultSet.getIdentifier();
|
||||||
|
|
||||||
|
assertFalse("check if resultset is not destroyed", resultSet.isDestroyed());
|
||||||
|
|
||||||
|
registry.addResultSet(resultSet);
|
||||||
|
resultSet.destroy();
|
||||||
|
|
||||||
|
assertTrue("check if resultset is destroyed", resultSet.isDestroyed());
|
||||||
|
assertNull("check if the object is pruned from the registry", registry.getResultSetById(rsId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*; // NOPMD
|
||||||
|
import static org.mockito.Mockito.*; // NOPMD
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset service rmi implementation test.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ResultSetServiceImplTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mock resultset id.
|
||||||
|
*/
|
||||||
|
private static final String RS_ID = "123";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instance under test.
|
||||||
|
*/
|
||||||
|
private transient ResultSetServiceImpl service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* custom property dao mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetPropertyDao customPropertyDao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset registry mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetRegistry resultsetRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset instance mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSet resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup.
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
service = new ResultSetServiceImpl();
|
||||||
|
service.setCustomPropertyDao(customPropertyDao);
|
||||||
|
service.setResultsetRegistry(resultsetRegistry);
|
||||||
|
|
||||||
|
when(resultsetRegistry.getResultSetById(RS_ID)).thenReturn(resultSet);
|
||||||
|
when(resultSet.getIdentifier()).thenReturn(RS_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test get property.
|
||||||
|
* @throws ResultSetException shouldn't happen
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetProperty() throws ResultSetException {
|
||||||
|
final Map<String, String> properties = new HashMap<String, String>();
|
||||||
|
properties.put("prefetch", "true");
|
||||||
|
|
||||||
|
when(customPropertyDao.getProperties(resultSet)).thenReturn(properties);
|
||||||
|
when(resultSet.getNumberOfResults()).thenReturn(1);
|
||||||
|
|
||||||
|
assertEquals("test builtin", "1", service.getProperty(RS_ID, "total"));
|
||||||
|
assertEquals("test builtin", RS_ID, service.getProperty(RS_ID, "rsId"));
|
||||||
|
|
||||||
|
assertEquals("test custom", "true", service.getProperty(RS_ID, "prefetch"));
|
||||||
|
assertNull("test custom", service.getProperty(RS_ID, "unexistent"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get resultset status.
|
||||||
|
*
|
||||||
|
* @throws ResultSetException shouldn't happen
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetRSStatus() throws ResultSetException {
|
||||||
|
when(resultSet.isOpen()).thenReturn(true);
|
||||||
|
|
||||||
|
assertEquals("check open", service.getRSStatus(RS_ID), "open");
|
||||||
|
|
||||||
|
when(resultSet.isOpen()).thenReturn(false);
|
||||||
|
assertEquals("check closed", service.getRSStatus(RS_ID), "closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package eu.dnetlib.enabling.resultset;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
public class StreamingResultSetListenerTest {
|
||||||
|
|
||||||
|
private StreamingResultSetListener listener;
|
||||||
|
private List<String> data;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
data = Lists.newArrayList("uno", "due", "tre", "quattro");
|
||||||
|
listener = new StreamingResultSetListener(data.iterator(), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult() {
|
||||||
|
assertEquals(data.size(), listener.getSize());
|
||||||
|
|
||||||
|
final List<String> res = listener.getResult(1, 2);
|
||||||
|
assertEquals(2, res.size());
|
||||||
|
assertEquals("uno", res.get(0));
|
||||||
|
assertEquals("due", res.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult2() {
|
||||||
|
listener.getResult(1, 2);
|
||||||
|
final List<String> res = listener.getResult(3, 4);
|
||||||
|
assertEquals(2, res.size());
|
||||||
|
assertEquals("tre", res.get(0));
|
||||||
|
assertEquals("quattro", res.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResult_retry() {
|
||||||
|
listener.getResult(1, 2);
|
||||||
|
final List<String> res = listener.getResult(1, 2);
|
||||||
|
assertEquals(2, res.size());
|
||||||
|
assertEquals("uno", res.get(0));
|
||||||
|
assertEquals("due", res.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testGetResult_random() {
|
||||||
|
listener.getResult(1, 2);
|
||||||
|
listener.getResult(2, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testGetResult_skip() {
|
||||||
|
listener.getResult(1, 2);
|
||||||
|
listener.getResult(4, 4);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
package eu.dnetlib.enabling.resultset; // NOPMD
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.mockito.Matchers.anyObject;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.argThat;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.transform.TransformerConfigurationException;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentMatcher;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||||
|
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||||
|
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test xslt resultset.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class XSLTMappedResultSetFactoryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instance under test.
|
||||||
|
*/
|
||||||
|
private transient XSLTMappedResultSetFactory factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset factory mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetFactory resultSetFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* service resolver.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ServiceResolver serviceResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset service mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetService resultSetService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* underlying resultSet mock
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSet resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common setup.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
factory = new XSLTMappedResultSetFactory();
|
||||||
|
factory.setResultSetFactory(resultSetFactory);
|
||||||
|
factory.setServiceResolver(serviceResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test invalid xslt.
|
||||||
|
*
|
||||||
|
* @throws TransformerConfigurationException
|
||||||
|
* could happen
|
||||||
|
*/
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void testInvalidXslt() throws TransformerConfigurationException {
|
||||||
|
factory.createMappedResultSet(null, "<bla/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test xslt.
|
||||||
|
*
|
||||||
|
* @throws TransformerConfigurationException
|
||||||
|
* could happen
|
||||||
|
* @throws IOException
|
||||||
|
* could happen
|
||||||
|
* @throws ResultSetException mock
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testXslt() throws TransformerConfigurationException, IOException, ResultSetException {
|
||||||
|
when(serviceResolver.getService(eq(ResultSetService.class), (W3CEndpointReference) anyObject())).thenReturn(resultSetService);
|
||||||
|
when(serviceResolver.getResourceIdentifier((W3CEndpointReference) anyObject())).thenReturn("123");
|
||||||
|
|
||||||
|
//when(resultSetService.getNumberOfElements(anyString())).thenReturn(1);
|
||||||
|
when(resultSetService.getResult("123", 1, 1, "waiting")).thenReturn(Lists.newArrayList("<first>something</first>"));
|
||||||
|
when(resultSetService.getRSStatus("123")).thenReturn("closed");
|
||||||
|
|
||||||
|
when(resultSet.isOpen()).thenReturn(true);
|
||||||
|
|
||||||
|
final StringWriter xsltSource = new StringWriter();
|
||||||
|
IOUtils.copy(getClass().getResourceAsStream("test.xsl"), xsltSource);
|
||||||
|
factory.createMappedResultSet(null, xsltSource.toString());
|
||||||
|
|
||||||
|
verify(resultSetFactory, times(1)).createResultSet(argThat(new ArgumentMatcher<ResultSetListener>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(final ResultSetListener argument) {
|
||||||
|
final MappedResultSet listener = (MappedResultSet) argument;
|
||||||
|
listener.setResultSet(resultSet);
|
||||||
|
final List<String> res = listener.getResult(1, 1);
|
||||||
|
|
||||||
|
assertNotNull("null result", res);
|
||||||
|
assertFalse("empty result", res.isEmpty());
|
||||||
|
|
||||||
|
assertNotNull("null element", res.get(0));
|
||||||
|
|
||||||
|
assertTrue("transformed correctly", res.get(0).contains("<second>something</second>"));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*; // NOPMD
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.cache.Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* subclass this unit test class and provide a concrete transient push resultset dao implementation.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Ignore
|
||||||
|
public abstract class AbstractTransientPushResultSetDaoTest {
|
||||||
|
/**
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
private static final Log log = LogFactory.getLog(AbstractTransientPushResultSetDaoTest.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test first element.
|
||||||
|
*/
|
||||||
|
private static final String TWO = "two";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test second element.
|
||||||
|
*/
|
||||||
|
private static final String ONE = "one";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* some key.
|
||||||
|
*/
|
||||||
|
private static final String RS_ID = "123";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instance under test.
|
||||||
|
*/
|
||||||
|
private TransientPushResultSetDao dao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prepare the instance under test.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
setDao(newInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* specific unit tests will override this method and provide a concrete instance to test.
|
||||||
|
*
|
||||||
|
* @return new transient push resultset dao instance
|
||||||
|
*/
|
||||||
|
protected abstract TransientPushResultSetDao newInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test add elements.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddElements() {
|
||||||
|
final List<String> freshGet = getDao().getElements(RS_ID, 1, 0);
|
||||||
|
assertNotNull("fresh get", freshGet);
|
||||||
|
assertEquals("fresh get", 0, freshGet.size());
|
||||||
|
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
list.add(ONE);
|
||||||
|
|
||||||
|
getDao().addElements(RS_ID, list);
|
||||||
|
|
||||||
|
final List<String> firstGet = getDao().getElements(RS_ID, 1, 1);
|
||||||
|
assertEquals("first get", 1, firstGet.size());
|
||||||
|
assertEquals("first get", ONE, firstGet.get(0));
|
||||||
|
|
||||||
|
final List<String> listAppend = new ArrayList<String>();
|
||||||
|
listAppend.add(TWO);
|
||||||
|
|
||||||
|
getDao().addElements(RS_ID, listAppend);
|
||||||
|
|
||||||
|
final List<String> secondGet = getDao().getElements(RS_ID, 1, 2);
|
||||||
|
assertEquals("second get", 2, secondGet.size());
|
||||||
|
assertEquals("second get", ONE, secondGet.get(0));
|
||||||
|
assertEquals("second get", TWO, secondGet.get(1));
|
||||||
|
|
||||||
|
final List<String> listBig = new ArrayList<String>();
|
||||||
|
for (int i = 0; i < 90; i++)
|
||||||
|
listBig.add(Integer.toString(i));
|
||||||
|
|
||||||
|
getDao().addElements(RS_ID, listBig);
|
||||||
|
|
||||||
|
final List<String> thirdGet = getDao().getElements(RS_ID, 3, 90);
|
||||||
|
assertEquals("third get", 88, thirdGet.size());
|
||||||
|
assertEquals("third get", "0", thirdGet.get(0));
|
||||||
|
assertEquals("third get", "1", thirdGet.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check get elements.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetElements() {
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
list.add(ONE);
|
||||||
|
|
||||||
|
getDao().addElements(RS_ID, list);
|
||||||
|
|
||||||
|
final List<String> res = getDao().getElements(RS_ID, 1, 1);
|
||||||
|
assertEquals("check size", 1, res.size());
|
||||||
|
assertEquals("check element", ONE, res.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* introduced for reproducing of #904. Thanks to Jochen for this one.
|
||||||
|
*/
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testAddElementsDifferentSize() {
|
||||||
|
List<Integer> sizes = Lists.newArrayList(100, 200, 300, 99);
|
||||||
|
int run = 0;
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
List<String> records = new LinkedList<String>();
|
||||||
|
for (int size : sizes) {
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
records.add("bla-" + run + "-" + i);
|
||||||
|
|
||||||
|
dao.addElements(RS_ID, records);
|
||||||
|
records.clear();
|
||||||
|
|
||||||
|
total += size;
|
||||||
|
run++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("check size", total, dao.getSize(RS_ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* introduced for reproducing of #904. with correct size (limited by 100)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddElementsDifferentSizeCorrectSize() {
|
||||||
|
List<Integer> sizes = Lists.newArrayList(51, 51, 51, 51);
|
||||||
|
|
||||||
|
int total = 0;
|
||||||
|
int run = 0;
|
||||||
|
String lastName = null;
|
||||||
|
|
||||||
|
List<String> records = new LinkedList<String>();
|
||||||
|
for (int size : sizes) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
lastName = "bla-" + run + "-" + i;
|
||||||
|
records.add(lastName);
|
||||||
|
}
|
||||||
|
|
||||||
|
dao.addElements(RS_ID, records);
|
||||||
|
records.clear();
|
||||||
|
|
||||||
|
total += size;
|
||||||
|
run++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inspect();
|
||||||
|
|
||||||
|
assertEquals("check size", total, dao.getSize(RS_ID));
|
||||||
|
assertEquals("check last", lastName, dao.getElements(RS_ID, total, total).get(0));
|
||||||
|
|
||||||
|
assertEquals("check first page", "bla-0-11", dao.getElements(RS_ID, 12, 12).get(0));
|
||||||
|
assertEquals("check last page", "bla-1-11", dao.getElements(RS_ID, 51 + 12, 51 + 12).get(0));
|
||||||
|
|
||||||
|
assertEquals("check range", 10, dao.getElements(RS_ID, 1, 10).size());
|
||||||
|
assertEquals("check range", 10, dao.getElements(RS_ID, 51 + 1, 51 + 10).size());
|
||||||
|
assertEquals("check range", 51, dao.getElements(RS_ID, 1, 51).size());
|
||||||
|
assertEquals("check range", 52, dao.getElements(RS_ID, 1, 52).size());
|
||||||
|
assertEquals("check range", 51, dao.getElements(RS_ID, 2, 52).size());
|
||||||
|
|
||||||
|
assertEquals("check range", 100, dao.getElements(RS_ID, 1, 100).size());
|
||||||
|
assertEquals("check range", 99, dao.getElements(RS_ID, 2, 100).size());
|
||||||
|
assertEquals("check range", 100, dao.getElements(RS_ID, 2, 101).size());
|
||||||
|
|
||||||
|
assertEquals("check range", 200, dao.getElements(RS_ID, 2, 201).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inspect() {
|
||||||
|
CacheTransientResultSetDaoImpl dao = (CacheTransientResultSetDaoImpl) this.dao;
|
||||||
|
ResultSetDescriptor desc = dao.getResultSetCache().get(RS_ID);
|
||||||
|
Cache<String, List<String>> cache = dao.getCache();
|
||||||
|
|
||||||
|
log.debug("----------------");
|
||||||
|
log.debug("ranges: " + desc.getRanges());
|
||||||
|
log.debug("last range index: " + desc.getLastRange());
|
||||||
|
for (int i = 0; i < desc.getRanges(); i++) {
|
||||||
|
final List<String> range = cache.get(RS_ID + "-" + i);
|
||||||
|
log.debug("range: " + i + " has " + range.size() + " elements");
|
||||||
|
log.debug(" " + range);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("----------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSizeOfEmpty() {
|
||||||
|
assertEquals("empty size", 0, dao.getSize(RS_ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransientPushResultSetDao getDao() {
|
||||||
|
return dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDao(final TransientPushResultSetDao dao) {
|
||||||
|
this.dao = dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sf.ehcache.CacheManager;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.cache.Cache;
|
||||||
|
import eu.dnetlib.miscutils.cache.EhCache;
|
||||||
|
import eu.dnetlib.miscutils.factory.Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* concrete push resultset dao test.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CacheTransientPushResultSetDaoTest extends AbstractTransientPushResultSetDaoTest { // NOPMD
|
||||||
|
|
||||||
|
/**
|
||||||
|
* max in memory elements.
|
||||||
|
*/
|
||||||
|
private static final int MAX_IN_MEM = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default time.
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_TTI = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default time to live.
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_TTL = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cache manager.
|
||||||
|
*/
|
||||||
|
private final transient CacheManager cacheManager = CacheManager.create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clean cache after test.
|
||||||
|
*/
|
||||||
|
@After
|
||||||
|
public void cleanCache() {
|
||||||
|
cacheManager.removeAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @see eu.dnetlib.enabling.resultset.push.AbstractTransientPushResultSetDaoTest#newInstance()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected TransientPushResultSetDao newInstance() {
|
||||||
|
final net.sf.ehcache.Cache ehcache = new net.sf.ehcache.Cache("testCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||||
|
cacheManager.addCache(ehcache);
|
||||||
|
|
||||||
|
final net.sf.ehcache.Cache rsehcache = new net.sf.ehcache.Cache("rsetCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||||
|
cacheManager.addCache(rsehcache);
|
||||||
|
|
||||||
|
final CacheTransientResultSetDaoImpl resultSet = new CacheTransientResultSetDaoImpl();
|
||||||
|
final Cache<String, List<String>> cache = new EhCache<String, List<String>>(ehcache);
|
||||||
|
final Cache<String, ResultSetDescriptor> rscache = new EhCache<String, ResultSetDescriptor>(rsehcache);
|
||||||
|
resultSet.setCache(cache);
|
||||||
|
resultSet.setResultSetCache(rscache);
|
||||||
|
|
||||||
|
resultSet.setResultSetDescriptorFactory(new Factory<ResultSetDescriptor>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSetDescriptor newInstance() {
|
||||||
|
return new ResultSetDescriptor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import eu.dnetlib.miscutils.factory.Factory;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration
|
||||||
|
public class ResultSetDescriptorFactoryTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
Factory<ResultSetDescriptor> factory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFactory() {
|
||||||
|
ResultSetDescriptor desc1 = factory.newInstance();
|
||||||
|
ResultSetDescriptor desc2 = factory.newInstance();
|
||||||
|
|
||||||
|
assertTrue("check different instances", desc1 != desc2);
|
||||||
|
assertEquals("check that it's a spring prototype", 200, desc1.getRangeLength());
|
||||||
|
assertEquals("check that it's a spring prototype", 200, desc2.getRangeLength());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.push.ResultSetDescriptor.Range;
|
||||||
|
|
||||||
|
public class ResultSetDescriptorTest {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(ResultSetDescriptorTest.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||||
|
|
||||||
|
private transient ResultSetDescriptor descriptor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
descriptor = new ResultSetDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetRangesContaining() {
|
||||||
|
log.debug("--- 1, 1");
|
||||||
|
for(Range i : descriptor.getRangesContaining(1, 1))
|
||||||
|
log.debug("i " + i);
|
||||||
|
|
||||||
|
log.debug("--- 2, 1000");
|
||||||
|
for(Range i : descriptor.getRangesContaining(2, 1000))
|
||||||
|
log.debug("i " + i);
|
||||||
|
|
||||||
|
log.debug("--- 5, 2000");
|
||||||
|
for(Range i : descriptor.getRangesContaining(5, 2000))
|
||||||
|
log.debug("i " + i);
|
||||||
|
|
||||||
|
log.debug("--- 5, 2001");
|
||||||
|
for(Range i : descriptor.getRangesContaining(5, 2001))
|
||||||
|
log.debug("i " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNext() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
package eu.dnetlib.enabling.resultset.push;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*; // NOPMD
|
||||||
|
import static org.mockito.Mockito.*; // NOPMD
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import eu.dnetlib.enabling.resultset.ResultSetRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test the transient push resultset.
|
||||||
|
*
|
||||||
|
* @author marko
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class TransientPushResultSetImplTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* first test value.
|
||||||
|
*/
|
||||||
|
private static final String ONE = "one";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* second test value.
|
||||||
|
*/
|
||||||
|
private static final String TWO = "two";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test rs id.
|
||||||
|
*/
|
||||||
|
private static final String RS_ID = "123";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instance to be tested.
|
||||||
|
*/
|
||||||
|
private transient TransientPushResultSetImpl resultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dao mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient TransientPushResultSetDao dao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resultset registry mock.
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private transient ResultSetRegistry registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup class to be tested.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
resultSet = new TransientPushResultSetImpl(dao);
|
||||||
|
resultSet.setIdentifier(RS_ID);
|
||||||
|
resultSet.getDao(); // getter code coverage hack
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test adding elements.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddElements() {
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
list.add(ONE);
|
||||||
|
|
||||||
|
resultSet.addElements(list);
|
||||||
|
|
||||||
|
verify(dao).addElements(RS_ID, list);
|
||||||
|
assertNotNull("dummy", resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test get number of results.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetNumberOfResults() {
|
||||||
|
when(dao.getSize(RS_ID)).thenReturn(1);
|
||||||
|
|
||||||
|
assertEquals("check size", 1, resultSet.getNumberOfResults());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get result.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetResults() {
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
list.add(TWO);
|
||||||
|
|
||||||
|
when(dao.getSize(RS_ID)).thenReturn(2);
|
||||||
|
when(dao.getElements(RS_ID, 2, 2)).thenReturn(list);
|
||||||
|
|
||||||
|
assertEquals("check list", TWO, resultSet.getResults(2, 2).get(0));
|
||||||
|
assertEquals("check size", 1, resultSet.getResults(2, 2).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test when indices are out of range, trailing stuff should be skipped.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetResultOutOfRange() {
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
list.add(TWO);
|
||||||
|
|
||||||
|
when(dao.getSize(RS_ID)).thenReturn(2);
|
||||||
|
when(dao.getElements(RS_ID, 2, 2)).thenReturn(list);
|
||||||
|
|
||||||
|
assertEquals("check list", TWO, resultSet.getResults(2, 2 + 1).get(0));
|
||||||
|
assertEquals("check size", 1, resultSet.getResults(2, 2 + 1).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* open.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testIsOpen() {
|
||||||
|
assertTrue("check is open by default", resultSet.isOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test close.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testClose() {
|
||||||
|
resultSet.addObserver(registry);
|
||||||
|
assertEquals("observer should be added", 1, resultSet.countObservers());
|
||||||
|
|
||||||
|
resultSet.destroy();
|
||||||
|
assertTrue("should be destroyed", resultSet.isDestroyed());
|
||||||
|
|
||||||
|
assertEquals("observers should be cleared", 0, resultSet.countObservers());
|
||||||
|
verify(registry, times(1)).update(resultSet, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromAfterSize() {
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
list.add(TWO);
|
||||||
|
|
||||||
|
when(dao.getSize(RS_ID)).thenReturn(2);
|
||||||
|
when(dao.getElements(RS_ID, 2, 2)).thenReturn(list);
|
||||||
|
|
||||||
|
resultSet.getResults(3, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void testWriteClosed() {
|
||||||
|
resultSet.close();
|
||||||
|
resultSet.addElements(Lists.newArrayList("test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||||
|
|
||||||
|
<bean id="resultSetDescriptorPrototype" class="eu.dnetlib.enabling.resultset.push.ResultSetDescriptor"
|
||||||
|
p:rangeLength="200" scope="prototype" />
|
||||||
|
|
||||||
|
<bean id="resultSetDescriptorFactory" class="eu.dnetlib.springutils.beans.factory.PrototypeFactory">
|
||||||
|
<lookup-method name="newInstance" bean="resultSetDescriptorPrototype" />
|
||||||
|
</bean>
|
||||||
|
</beans>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<xsl:stylesheet version="1.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
<xsl:template match="first">
|
||||||
|
<second><xsl:value-of select="."/></second>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
25
pom.xml
25
pom.xml
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>dnet-core-components</module>
|
<module>dnet-core-components</module>
|
||||||
|
<module>dnet-core-services</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,13 +142,6 @@
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>${google.gson.version}</version>
|
<version>${google.gson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.9</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
|
@ -230,6 +224,12 @@
|
||||||
<version>1.7</version>
|
<version>1.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.9</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
|
@ -336,7 +336,16 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
Loading…
Reference in New Issue