259 lines
8.8 KiB
Java
259 lines
8.8 KiB
Java
package org.gcube.data.spd.resources;
|
|
|
|
import java.net.URI;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import javax.ws.rs.GET;
|
|
import javax.ws.rs.Path;
|
|
import javax.ws.rs.QueryParam;
|
|
import javax.ws.rs.core.Response;
|
|
|
|
import org.gcube.common.authorization.library.AuthorizedTasks;
|
|
import org.gcube.data.spd.exception.MaxRetriesReachedException;
|
|
import org.gcube.data.spd.manager.AppInitializer;
|
|
import org.gcube.data.spd.manager.OccurrenceWriterManager;
|
|
import org.gcube.data.spd.model.Constants;
|
|
import org.gcube.data.spd.model.exceptions.ExternalRepositoryException;
|
|
import org.gcube.data.spd.model.exceptions.IdNotValidException;
|
|
import org.gcube.data.spd.model.exceptions.StreamBlockingException;
|
|
import org.gcube.data.spd.model.products.OccurrencePoint;
|
|
import org.gcube.data.spd.plugin.PluginManager;
|
|
import org.gcube.data.spd.plugin.fwk.AbstractPlugin;
|
|
import org.gcube.data.spd.plugin.fwk.capabilities.OccurrencesCapability;
|
|
import org.gcube.data.spd.plugin.fwk.readers.LocalReader;
|
|
import org.gcube.data.spd.plugin.fwk.util.Util;
|
|
import org.gcube.data.spd.plugin.fwk.writers.Writer;
|
|
import org.gcube.data.spd.plugin.fwk.writers.rswrapper.AbstractWrapper;
|
|
import org.gcube.data.spd.plugin.fwk.writers.rswrapper.LocalWrapper;
|
|
import org.gcube.data.spd.plugin.fwk.writers.rswrapper.ResultWrapper;
|
|
import org.gcube.data.spd.utils.ExecutorsContainer;
|
|
import org.gcube.data.spd.utils.QueryRetryCall;
|
|
import org.gcube.data.spd.utils.ResultWrapperMantainer;
|
|
import org.gcube.data.spd.utils.VOID;
|
|
import org.gcube.data.streams.Stream;
|
|
import org.gcube.data.streams.dsl.Streams;
|
|
import org.gcube.smartgears.ApplicationManagerProvider;
|
|
import org.gcube.smartgears.ContextProvider;
|
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
@Path("occurrence")
|
|
public class Occurrences{
|
|
|
|
Logger logger = LoggerFactory.getLogger(Occurrences.class);
|
|
|
|
ApplicationContext ctx = ContextProvider.get();
|
|
|
|
AppInitializer initializer = (AppInitializer) ApplicationManagerProvider.get(AppInitializer.class);
|
|
|
|
public enum ExecType {
|
|
IDS,
|
|
KEYS
|
|
}
|
|
|
|
|
|
@GET
|
|
@Path("keys")
|
|
public Response getByKeys(@QueryParam("keys") List<String> keys) {
|
|
try{
|
|
|
|
logger.trace("keys arrived are {} ",keys);
|
|
|
|
Stream<String> reader = Streams.convert(keys.iterator());
|
|
|
|
ResultWrapper<OccurrencePoint> wrapper = ResultWrapperMantainer.getWrapper(OccurrencePoint.class);
|
|
|
|
logger.trace("entering in the getOccurrence by productKeys with keys {}",keys);
|
|
ExecutorsContainer.execJob(AuthorizedTasks.bind(new RunnableOccurrenceSearch(reader, wrapper, ExecType.KEYS)));
|
|
|
|
// the output will be probably returned even before
|
|
// a first chunk is written by the new thread
|
|
StringBuilder redirectUri = new StringBuilder();
|
|
redirectUri.append("http://").append(ctx.container().configuration().hostname()).append(":").append(ctx.container().configuration().port());
|
|
redirectUri.append(ctx.application().getContextPath()).append(Constants.APPLICATION_ROOT_PATH).append("/").append(Constants.RESULTSET_PATH).append("/").append(wrapper.getLocator());
|
|
logger.trace("redirect uri is {} ",redirectUri.toString());
|
|
try{
|
|
return Response.temporaryRedirect(new URI(redirectUri.toString())).build();
|
|
}catch(Exception e){
|
|
logger.error("invalid redirect uri created",e);
|
|
return Response.serverError().build();
|
|
}
|
|
}catch (Exception e) {
|
|
logger.error("error getting occurrences by ids",e);
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@GET
|
|
@Path("ids")
|
|
public Response getByIds(@QueryParam("ids") List<String> ids){
|
|
try{
|
|
Stream<String> reader = Streams.convert(ids.iterator());
|
|
|
|
ResultWrapper<OccurrencePoint> wrapper = ResultWrapperMantainer.getWrapper(OccurrencePoint.class);
|
|
ExecutorsContainer.execJob(AuthorizedTasks.bind(new RunnableOccurrenceSearch(reader, wrapper, ExecType.IDS)));
|
|
// the output will be probably returned even before
|
|
// a first chunk is written by the new thread
|
|
StringBuilder redirectUri = new StringBuilder();
|
|
redirectUri.append("http://").append(ctx.container().configuration().hostname()).append(":").append(ctx.container().configuration().port());
|
|
redirectUri.append(ctx.application().getContextPath()).append(Constants.APPLICATION_ROOT_PATH).append("/").append(Constants.RESULTSET_PATH).append("/").append(wrapper.getLocator());
|
|
logger.trace("redirect uri is {} ",redirectUri.toString());
|
|
try{
|
|
return Response.temporaryRedirect(new URI(redirectUri.toString())).build();
|
|
}catch(Exception e){
|
|
logger.error("invalid redirect uri created",e);
|
|
return Response.serverError().build();
|
|
}
|
|
}catch (Exception e) {
|
|
logger.error("error getting occurrences by ids");
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
|
|
public class RunnableOccurrenceSearch implements Runnable{
|
|
|
|
private Stream<String> reader;
|
|
private ResultWrapper<OccurrencePoint> wrapper;
|
|
private ExecType execType;
|
|
|
|
public RunnableOccurrenceSearch(Stream<String> reader,
|
|
ResultWrapper<OccurrencePoint> wrapper, ExecType execType) {
|
|
super();
|
|
this.reader = reader;
|
|
this.wrapper = wrapper;
|
|
this.execType = execType;
|
|
}
|
|
|
|
@Override
|
|
public void run(){
|
|
Map<String, Writer<String>> pluginMap= new HashMap<String, Writer<String>>();
|
|
while (reader.hasNext()){
|
|
String key = reader.next();
|
|
try{
|
|
final String provider = Util.getProviderFromKey(key);
|
|
String id = Util.getIdFromKey(key);
|
|
logger.trace("key arrived "+id+" for provider "+provider);
|
|
if (!pluginMap.containsKey(provider)){
|
|
final LocalWrapper<String> localWrapper = new LocalWrapper<String>();
|
|
Writer<String> localWriter = new Writer<String>(localWrapper);
|
|
//localWriter.register();
|
|
pluginMap.put(provider, localWriter);
|
|
if (execType == ExecType.KEYS)
|
|
ExecutorsContainer.execSearch(AuthorizedTasks.bind(new RunnableOccurrenceByKeys(provider, wrapper, localWrapper)));
|
|
else ExecutorsContainer.execSearch(AuthorizedTasks.bind(new RunnableOccurrenceByIds(provider, wrapper, localWrapper)));
|
|
}
|
|
logger.trace("key put "+id+"? "+( pluginMap.get(provider).write(id)));
|
|
}catch (IdNotValidException e) {
|
|
logger.warn("the key "+key+" is not valid");
|
|
}
|
|
}
|
|
logger.trace("is wrapper closed? "+wrapper.isClosed());
|
|
if (pluginMap.values().isEmpty())
|
|
wrapper.close();
|
|
else
|
|
for (Writer<String> entry : pluginMap.values())
|
|
entry.close();
|
|
reader.close();
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
public class RunnableOccurrenceByKeys implements Runnable{
|
|
|
|
private String provider;
|
|
private AbstractWrapper<OccurrencePoint> wrapper;
|
|
private LocalWrapper<String> localWrapper;
|
|
|
|
|
|
|
|
public RunnableOccurrenceByKeys(String provider,
|
|
AbstractWrapper<OccurrencePoint> wrapper,
|
|
LocalWrapper<String> localWrapper) {
|
|
super();
|
|
this.provider = provider;
|
|
this.wrapper = wrapper;
|
|
this.localWrapper = localWrapper;
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
public void run(){
|
|
logger.trace("call to provider "+provider);
|
|
final Writer<OccurrencePoint> writer = new Writer<OccurrencePoint>(wrapper, new OccurrenceWriterManager(provider));
|
|
writer.register();
|
|
try {
|
|
new QueryRetryCall(){
|
|
|
|
@Override
|
|
protected VOID execute() throws ExternalRepositoryException {
|
|
PluginManager pm = initializer.getPluginManager();
|
|
AbstractPlugin plugin = pm.plugins().get(provider);
|
|
OccurrencesCapability oc = plugin.getOccurrencesInterface();
|
|
oc.getOccurrencesByProductKeys(writer, new LocalReader<String>(localWrapper));
|
|
return VOID.instance();
|
|
}
|
|
|
|
}.call();
|
|
} catch (MaxRetriesReachedException e) {
|
|
writer.write(new StreamBlockingException(provider));
|
|
}
|
|
writer.close();
|
|
logger.trace("writer is closed ? "+(!writer.isAlive()));
|
|
}
|
|
|
|
}
|
|
|
|
public class RunnableOccurrenceByIds implements Runnable{
|
|
|
|
private String provider;
|
|
private AbstractWrapper<OccurrencePoint> wrapper;
|
|
private LocalWrapper<String> localWrapper;
|
|
|
|
|
|
|
|
public RunnableOccurrenceByIds(String provider,
|
|
AbstractWrapper<OccurrencePoint> wrapper,
|
|
LocalWrapper<String> localWrapper) {
|
|
super();
|
|
this.provider = provider;
|
|
this.wrapper = wrapper;
|
|
this.localWrapper = localWrapper;
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
public void run(){
|
|
logger.trace("call to provider "+provider);
|
|
final Writer<OccurrencePoint> writer = new Writer<OccurrencePoint>(wrapper, new OccurrenceWriterManager(provider));
|
|
writer.register();
|
|
try {
|
|
new QueryRetryCall(){
|
|
|
|
@Override
|
|
protected VOID execute() throws ExternalRepositoryException {
|
|
PluginManager pm = initializer.getPluginManager();
|
|
AbstractPlugin plugin = pm.plugins().get(provider);
|
|
OccurrencesCapability oc = plugin.getOccurrencesInterface();
|
|
oc.getOccurrencesByIds(writer, new LocalReader<String>(localWrapper)); return VOID.instance();
|
|
}
|
|
|
|
}.call();
|
|
} catch (MaxRetriesReachedException e) {
|
|
writer.write(new StreamBlockingException(provider));
|
|
}
|
|
|
|
writer.close();
|
|
}
|
|
|
|
}
|
|
|
|
}
|