Skip to content
Snippets Groups Projects
Commit 30881a59 authored by HongKee Moon's avatar HongKee Moon
Browse files

Handle multiple datasets with different contexts and XML file provided through http

For example, if BigDataViewer uses http://localhost:8080/HisYFP-SPIM, it will process the xml file directly and access the remote BigDataServer.
parent ca111bc7
No related branches found
No related tags found
No related merge requests found
package bdv.server; package bdv.server;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import mpicbg.spim.data.SpimDataException;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
import net.imglib2.realtransform.AffineTransform3D;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import bdv.img.cache.CacheHints;
import bdv.img.cache.LoadingStrategy;
import bdv.img.cache.VolatileCell;
import bdv.img.cache.VolatileGlobalCellCache;
import bdv.img.hdf5.Hdf5ImageLoader;
import bdv.img.remote.AffineTransform3DJsonSerializer;
import bdv.img.remote.RemoteImageLoaderMetaData;
import bdv.spimdata.SequenceDescriptionMinimal;
import bdv.spimdata.SpimDataMinimal;
import bdv.spimdata.XmlIoSpimDataMinimal;
import com.google.gson.GsonBuilder; import java.util.HashMap;
public class BigDataServer public class BigDataServer
{ {
static HashMap< String, String > dataSet = new HashMap<>();
public static void main( final String[] args ) throws Exception public static void main( final String[] args ) throws Exception
{ {
final String fn = args.length > 0 ? args[ 0 ] : "/Users/pietzsch/Desktop/data/fibsem.xml"; final String fn = args.length > 0 ? args[ 0 ] : "/Users/moon/Projects/git-projects/BigDataViewer/data/HisYFP-SPIM.xml";
dataSet.put( "HisYFP-SPIM", fn );
final int port = args.length > 1 ? Integer.parseInt( args[ 1 ] ) : 8080; final int port = args.length > 1 ? Integer.parseInt( args[ 1 ] ) : 8080;
System.setProperty( "org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog" ); System.setProperty( "org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog" );
final Server server = new Server( port ); final Server server = new Server( port );
server.setHandler( new CellHandler( fn ) );
server.start();
server.join();
}
static class CellHandler extends AbstractHandler
{
private final VolatileGlobalCellCache< VolatileShortArray > cache;
private final String metadataJson; String baseURL = "http://" + server.getURI().getHost() + ":" + port + "/";
private final RemoteImageLoaderMetaData metadata; // System.out.println(baseURL);
private final CacheHints cacheHints; server.setHandler( new DataSetHandler( baseURL, dataSet ) );
server.start();
public CellHandler( final String xmlFilename ) throws SpimDataException server.join();
{
final SpimDataMinimal spimData = new XmlIoSpimDataMinimal().load( xmlFilename );
final SequenceDescriptionMinimal seq = spimData.getSequenceDescription();
final Hdf5ImageLoader imgLoader = ( Hdf5ImageLoader ) seq.getImgLoader();
cache = imgLoader.getCache();
metadata = new RemoteImageLoaderMetaData( imgLoader, seq );
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter( AffineTransform3D.class, new AffineTransform3DJsonSerializer() );
gsonBuilder.enableComplexMapKeySerialization();
metadataJson = gsonBuilder.create().toJson( metadata );
cacheHints = new CacheHints( LoadingStrategy.BLOCKING, 0, false );
}
@Override
public void handle( final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response ) throws IOException, ServletException
{
final String cellString = request.getParameter( "p" );
if ( cellString == null )
return;
final String[] parts = cellString.split( "/" );
if ( parts[ 0 ].equals( "cell" ) )
{
final int index = Integer.parseInt( parts[ 1 ] );
final int timepoint = Integer.parseInt( parts[ 2 ] );
final int setup = Integer.parseInt( parts[ 3 ] );
final int level = Integer.parseInt( parts[ 4 ] );
VolatileCell< VolatileShortArray > cell = cache.getGlobalIfCached( timepoint, setup, level, index, cacheHints );
if ( cell == null )
{
final int[] cellDims = new int[] {
Integer.parseInt( parts[ 5 ] ),
Integer.parseInt( parts[ 6 ] ),
Integer.parseInt( parts[ 7 ] ) };
final long[] cellMin = new long[] {
Long.parseLong( parts[ 8 ] ),
Long.parseLong( parts[ 9 ] ),
Long.parseLong( parts[ 10 ] ) };
cell = cache.createGlobal( cellDims, cellMin, timepoint, setup, level, index, cacheHints );
}
final short[] data = cell.getData().getCurrentStorageArray();
final byte[] buf = new byte[ 2 * data.length ];
for ( int i = 0, j = 0; i < data.length; i++ )
{
final short s = data[ i ];
buf[ j++ ] = ( byte ) ( ( s >> 8 ) & 0xff );
buf[ j++ ] = ( byte ) ( s & 0xff );
}
response.setContentType( "application/octet-stream" );
response.setContentLength( buf.length );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final OutputStream os = response.getOutputStream();
os.write( buf );
os.close();
}
else if ( parts[ 0 ].equals( "init" ) )
{
response.setContentType( "application/octet-stream" );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final PrintWriter ow = response.getWriter();
ow.write( metadataJson );
ow.close();
}
}
} }
} }
package bdv.server;
import bdv.img.cache.CacheHints;
import bdv.img.cache.LoadingStrategy;
import bdv.img.cache.VolatileCell;
import bdv.img.cache.VolatileGlobalCellCache;
import bdv.img.hdf5.Hdf5ImageLoader;
import bdv.img.remote.AffineTransform3DJsonSerializer;
import bdv.img.remote.RemoteImageLoaderMetaData;
import bdv.spimdata.SequenceDescriptionMinimal;
import bdv.spimdata.SpimDataMinimal;
import bdv.spimdata.XmlIoSpimDataMinimal;
import com.google.gson.GsonBuilder;
import mpicbg.spim.data.SpimDataException;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
import net.imglib2.realtransform.AffineTransform3D;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
public class CellHandler extends AbstractHandler
{
private final VolatileGlobalCellCache< VolatileShortArray > cache;
private final String metadataJson;
private final RemoteImageLoaderMetaData metadata;
private final CacheHints cacheHints;
private final String xmlFile;
private final String dataSetURL;
public CellHandler( final String baseUrl, final String xmlFilename ) throws SpimDataException
{
final SpimDataMinimal spimData = new XmlIoSpimDataMinimal().load( xmlFilename );
final SequenceDescriptionMinimal seq = spimData.getSequenceDescription();
final Hdf5ImageLoader imgLoader = ( Hdf5ImageLoader ) seq.getImgLoader();
cache = imgLoader.getCache();
metadata = new RemoteImageLoaderMetaData( imgLoader, seq );
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter( AffineTransform3D.class, new AffineTransform3DJsonSerializer() );
gsonBuilder.enableComplexMapKeySerialization();
metadataJson = gsonBuilder.create().toJson( metadata );
cacheHints = new CacheHints( LoadingStrategy.BLOCKING, 0, false );
// dataSetURL property is used for providing the XML file by replace SequenceDescription>ImageLoader>baseUrl
xmlFile = xmlFilename;
dataSetURL = baseUrl;
}
@Override
public void handle( final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response ) throws IOException, ServletException
{
final String cellString = request.getParameter( "p" );
if ( cellString == null )
return;
final String[] parts = cellString.split( "/" );
if ( parts[ 0 ].equals( "cell" ) )
{
final int index = Integer.parseInt( parts[ 1 ] );
final int timepoint = Integer.parseInt( parts[ 2 ] );
final int setup = Integer.parseInt( parts[ 3 ] );
final int level = Integer.parseInt( parts[ 4 ] );
VolatileCell< VolatileShortArray > cell = cache.getGlobalIfCached( timepoint, setup, level, index, cacheHints );
if ( cell == null )
{
final int[] cellDims = new int[] {
Integer.parseInt( parts[ 5 ] ),
Integer.parseInt( parts[ 6 ] ),
Integer.parseInt( parts[ 7 ] ) };
final long[] cellMin = new long[] {
Long.parseLong( parts[ 8 ] ),
Long.parseLong( parts[ 9 ] ),
Long.parseLong( parts[ 10 ] ) };
cell = cache.createGlobal( cellDims, cellMin, timepoint, setup, level, index, cacheHints );
}
final short[] data = cell.getData().getCurrentStorageArray();
final byte[] buf = new byte[ 2 * data.length ];
for ( int i = 0, j = 0; i < data.length; i++ )
{
final short s = data[ i ];
buf[ j++ ] = ( byte ) ( ( s >> 8 ) & 0xff );
buf[ j++ ] = ( byte ) ( s & 0xff );
}
response.setContentType( "application/octet-stream" );
response.setContentLength( buf.length );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final OutputStream os = response.getOutputStream();
os.write( buf );
os.close();
}
else if ( parts[ 0 ].equals( "init" ) )
{
response.setContentType( "application/octet-stream" );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final PrintWriter ow = response.getWriter();
ow.write( metadataJson );
ow.close();
}
}
public void provideXML( final Request baseRequest, final HttpServletResponse response ) throws IOException, ServletException
{
final SAXBuilder sax = new SAXBuilder();
Document doc;
try
{
doc = sax.build( xmlFile );
}
catch ( final Exception e )
{
throw new ServletException( e );
}
final Element root = doc.getRootElement();
final Element SequenceDescription = root.getChild( "SequenceDescription" );
final Element ImageLoader = SequenceDescription.getChild( "ImageLoader" );
ImageLoader.setAttribute( "format", "bdv.remote" );
ImageLoader.removeChild( "hdf5" );
final Element baseUrl = new Element( "baseUrl" );
baseUrl.setText( dataSetURL );
ImageLoader.setContent( baseUrl );
// System.out.println(ImageLoader.getAttribute( "format" ));
// System.out.println(ImageLoader.getValue());
response.setContentType( "application/xml" );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final PrintWriter ow = response.getWriter();
ow.write( new XMLOutputter().outputString( doc ) );
ow.close();
}
}
\ No newline at end of file
package bdv.server;
import mpicbg.spim.data.SpimDataException;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
public class DataSetHandler extends AbstractHandler
{
final private HashMap< String, CellHandler > cellHandlers;
public DataSetHandler( String baseURL, HashMap< String, String > ds ) throws SpimDataException, MalformedURLException
{
cellHandlers = new HashMap<>();
for ( String dataSet : ds.keySet() )
{
cellHandlers.put( dataSet, new CellHandler( baseURL + dataSet + "/", ds.get( dataSet ) ) );
}
}
@Override
public void handle( final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response ) throws IOException, ServletException
{
String dsName = target.replace( "/", "" );
if ( cellHandlers.containsKey( dsName ) )
{
if ( request.getParameter( "p" ) != null )
cellHandlers.get( dsName ).handle( target, baseRequest, request, response );
else
// Provide XML file
cellHandlers.get( dsName ).provideXML( baseRequest, response );
}
else
{
return;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment