Merge pull request #13 from nrenner/profile-upload

Profile upload
This commit is contained in:
abrensch 2014-05-24 20:57:05 +02:00
commit e17375adfd
6 changed files with 159 additions and 16 deletions

View file

@ -20,11 +20,14 @@ import btools.router.OsmNodeNamed;
import btools.router.OsmTrack; import btools.router.OsmTrack;
import btools.router.RoutingContext; import btools.router.RoutingContext;
import btools.router.RoutingEngine; import btools.router.RoutingEngine;
import btools.server.request.ProfileUploadHandler;
import btools.server.request.RequestHandler; import btools.server.request.RequestHandler;
import btools.server.request.ServerHandler; import btools.server.request.ServerHandler;
public class RouteServer extends Thread public class RouteServer extends Thread
{ {
public static final String PROFILE_UPLOAD_URL = "/brouter/profile";
public ServiceContext serviceContext; public ServiceContext serviceContext;
private Socket clientSocket = null; private Socket clientSocket = null;
@ -65,6 +68,23 @@ public class RouteServer extends Thread
{ {
handler = new ServerHandler( serviceContext, params ); handler = new ServerHandler( serviceContext, params );
} }
else if ( url.startsWith( PROFILE_UPLOAD_URL ) )
{
writeHttpHeader(bw);
String profileId = null;
if ( url.length() > PROFILE_UPLOAD_URL.length() + 1 )
{
// e.g. /brouter/profile/custom_1400767688382
profileId = url.substring(PROFILE_UPLOAD_URL.length() + 1);
}
ProfileUploadHandler uploadHandler = new ProfileUploadHandler( serviceContext );
uploadHandler.handlePostRequest( profileId, br, bw );
bw.flush();
return;
}
else else
{ {
throw new IllegalArgumentException( "unknown request syntax: " + getline ); throw new IllegalArgumentException( "unknown request syntax: " + getline );
@ -76,12 +96,7 @@ public class RouteServer extends Thread
cr.quite = true; cr.quite = true;
cr.doRun( maxRunningTime ); cr.doRun( maxRunningTime );
// http-header writeHttpHeader(bw);
bw.write( "HTTP/1.1 200 OK\n" );
bw.write( "Connection: close\n" );
bw.write( "Content-Type: text/xml; charset=utf-8\n" );
bw.write( "Access-Control-Allow-Origin: *\n" );
bw.write( "\n" );
if ( cr.getErrorMessage() != null ) if ( cr.getErrorMessage() != null )
{ {
@ -115,22 +130,24 @@ public class RouteServer extends Thread
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
System.out.println("BRouter 0.9.9 / 18042014 / abrensch"); System.out.println("BRouter 0.9.9 / 18042014 / abrensch");
if ( args.length != 4 ) if ( args.length != 5 )
{ {
System.out.println("serve BRouter protocol"); System.out.println("serve BRouter protocol");
System.out.println("usage: java RouteServer <segmentdir> <profiledir> <port> <maxthreads>"); System.out.println("usage: java RouteServer <segmentdir> <profiledir> <customprofiledir> <port> <maxthreads>");
return; return;
} }
ServiceContext serviceContext = new ServiceContext(); ServiceContext serviceContext = new ServiceContext();
serviceContext.segmentDir = args[0]; serviceContext.segmentDir = args[0];
System.setProperty( "profileBaseDir", args[1] ); serviceContext.profileDir = args[1];
System.setProperty( "profileBaseDir", serviceContext.profileDir );
serviceContext.customProfileDir = args[2];
int maxthreads = Integer.parseInt( args[3] ); int maxthreads = Integer.parseInt( args[4] );
TreeMap<Long,RouteServer> threadMap = new TreeMap<Long,RouteServer>(); TreeMap<Long,RouteServer> threadMap = new TreeMap<Long,RouteServer>();
ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[2])); ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[3]));
long last_ts = 0; long last_ts = 0;
for (;;) for (;;)
{ {
@ -187,4 +204,13 @@ public class RouteServer extends Thread
} }
return maxRunningTime; return maxRunningTime;
} }
private static void writeHttpHeader(BufferedWriter bw) throws IOException {
// http-header
bw.write( "HTTP/1.1 200 OK\n" );
bw.write( "Connection: close\n" );
bw.write( "Content-Type: text/xml; charset=utf-8\n" );
bw.write( "Access-Control-Allow-Origin: *\n" );
bw.write( "\n" );
}
} }

View file

@ -11,6 +11,8 @@ import btools.router.OsmNodeNamed;
public class ServiceContext public class ServiceContext
{ {
public String segmentDir; public String segmentDir;
public String profileDir;
public String customProfileDir;
public Map<String,String> profileMap = null; public Map<String,String> profileMap = null;
public List<OsmNodeNamed> nogoList; public List<OsmNodeNamed> nogoList;
} }

View file

@ -0,0 +1,106 @@
package btools.server.request;
import btools.server.ServiceContext;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* Custom profile uploads
*/
public class ProfileUploadHandler
{
// maximum number of characters (file size limit for custom profiles)
private static final int MAX_LENGTH = 100000;
// prefix for custom profile id to distinguish from default profiles
public static final String CUSTOM_PREFIX = "custom_";
private ServiceContext serviceContext;
public ProfileUploadHandler( ServiceContext serviceContext)
{
this.serviceContext = serviceContext;
}
public void handlePostRequest(String profileId, BufferedReader br, BufferedWriter response) throws IOException
{
BufferedWriter fileWriter = null;
try
{
String id;
if ( profileId != null )
{
// update existing file when id appended
id = profileId.substring( ProfileUploadHandler.CUSTOM_PREFIX.length() );
} else {
id = "" + System.currentTimeMillis();
}
File file = new File( getOrCreateCustomProfileDir(), id + ".brf" );
fileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream( file ) ) );
//StringWriter sw = new StringWriter(); bw = new BufferedWriter(sw);
// only profile text as content
readPostData(br, fileWriter, id);
fileWriter.flush();
//System.out.println("data: |" + sw.toString() + "|");
response.write("profileid=" + CUSTOM_PREFIX + id);
}
finally
{
if ( fileWriter != null ) try { fileWriter.close(); } catch( Exception e ) {}
}
}
private File getOrCreateCustomProfileDir()
{
// workaround: customProfileDir relative to profileDir, because RoutingEngine doesn't know custom profiles
File customProfileDir = new File(serviceContext.profileDir, serviceContext.customProfileDir);
if (!customProfileDir.exists())
{
customProfileDir.mkdir();
}
return customProfileDir;
}
// reads HTTP POST content from input into output stream/writer
private static void readPostData( BufferedReader ir, BufferedWriter bw, String id ) throws IOException
{
// Content-Type: text/plain;charset=UTF-8
for(;;)
{
// headers
String line = ir.readLine();
if ( line == null ) break;
// blank line before content after headers
if ( line.length() == 0 )
{
int numChars = 0;
// Content-Length header is in bytes (!= characters for UTF8),
// but Reader reads characters, so don't know number of characters to read
for(;;)
{
// read will block when false, occurs at end of stream rather than -1
if (!ir.ready()) break;
int c = ir.read();
if ( c == -1) break;
bw.write( c );
numChars++;
if (numChars > MAX_LENGTH)
throw new IOException("Maximum number of characters exceeded (" + MAX_LENGTH + ", " + id + ")");
}
break;
}
}
}
}

View file

@ -8,6 +8,7 @@ import btools.router.OsmNodeNamed;
import btools.router.OsmTrack; import btools.router.OsmTrack;
import btools.router.RoutingContext; import btools.router.RoutingContext;
import btools.server.ServiceContext; import btools.server.ServiceContext;
import java.io.File;
/** /**
* URL query parameter handler for web and standalone server. Supports all * URL query parameter handler for web and standalone server. Supports all
@ -38,7 +39,15 @@ public class ServerHandler extends RequestHandler {
{ {
RoutingContext rc = new RoutingContext(); RoutingContext rc = new RoutingContext();
rc.localFunction = params.get( "profile" ); String profile = params.get( "profile" );
// when custom profile replace prefix with directory path
if ( profile.startsWith( ProfileUploadHandler.CUSTOM_PREFIX ) )
{
String customProfile = profile.substring( ProfileUploadHandler.CUSTOM_PREFIX.length() );
profile = new File( serviceContext.customProfileDir, customProfile ).getPath();
}
rc.localFunction = profile;
rc.setAlternativeIdx(Integer.parseInt(params.get( "alternativeidx" ))); rc.setAlternativeIdx(Integer.parseInt(params.get( "alternativeidx" )));
List<OsmNodeNamed> nogoList = readNogoList(); List<OsmNodeNamed> nogoList = readNogoList();

View file

@ -1,9 +1,9 @@
@echo off @echo off
REM BRouter standalone server REM BRouter standalone server
REM java -cp brouter.jar btools.brouter.RouteServer <segmentdir> <profile-map> <port> REM java -cp brouter.jar btools.brouter.RouteServer <segmentdir> <profile-map> <customprofiledir> <port> <maxthreads>
set JAVA_OPTS=-Xmx128M -Xms128M -Xmn8M set JAVA_OPTS=-Xmx128M -Xms128M -Xmn8M
set CLASSPATH=../brouter.jar set CLASSPATH=../brouter.jar
java %JAVA_OPTS% -cp %CLASSPATH% btools.server.RouteServer ..\segments2 ..\profiles2 17777 1 java %JAVA_OPTS% -cp %CLASSPATH% btools.server.RouteServer ..\segments2 ..\profiles2 ..\customprofiles 17777 1

View file

@ -1,9 +1,9 @@
#!/bin/sh #!/bin/sh
# BRouter standalone server # BRouter standalone server
# java -cp brouter.jar btools.brouter.RouteServer <segmentdir> <profile-map> <port> # java -cp brouter.jar btools.brouter.RouteServer <segmentdir> <profile-map> <customprofiledir> <port> <maxthreads>
JAVA_OPTS="-Xmx128M -Xms128M -Xmn8M" JAVA_OPTS="-Xmx128M -Xms128M -Xmn8M"
CLASSPATH=../brouter.jar CLASSPATH=../brouter.jar
java $JAVA_OPTS -cp $CLASSPATH btools.server.RouteServer ../segments2 ../profiles2 17777 1 java $JAVA_OPTS -cp $CLASSPATH btools.server.RouteServer ../segments2 ../profiles2 ../customprofiles 17777 1