Author: gtrasuk
Date: Thu Nov 24 07:14:36 2011
New Revision: 1205741
URL: http://svn.apache.org/viewvc?rev=1205741&view=rev
Log:
Continuing work on classloading and codebase handling. Codebase server seems
to be working, with simple path mapping. However the contained Reggie does not
currently work. Suspect classpath issues.
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/Strings.java
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java?rev=1205741&r1=1205740&r2=1205741&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
(original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
Thu Nov 24 07:14:36 2011
@@ -52,6 +52,9 @@ public class MessageNames {
CANT_READ_START_PROPERTIES="cantReadStartProperties",
CLASSLOADER_IS="classLoaderIs",
CLASS_SERVER_INIT_FAILED="classServerInitFailed",
+ CLASS_SERVER_RECEIVED_REQUEST="classServerReceivedRequest",
+ CLASS_SERVER_RECEIVED_PROBE="classServerReceivedProbe",
+ CLASS_SERVER_REJECTED_PATH="classServerRejectedPath",
CODESOURCE_IS="codeSourceIs",
COMPLETED_SERVICE_DEPLOYMENT="completedServiceDeployment",
CONFIG_FILE="configFile",
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties?rev=1205741&r1=1205740&r2=1205741&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
Thu Nov 24 07:14:36 2011
@@ -31,6 +31,9 @@ cantConvertException=Can''t convert type
cantReadStartProperties=Can''t read starter configuration file ''{0}'' in
''{1}''.
classLoaderIs=ClassLoader for class {0} is {1}.
classServerInitFailed=Class Server initialization failed.
+classServerRejectedPath=Rejected request for path ''{0}'' (returning 404).
+classServerReceivedProbe={0} probed from {1}:{2}
+classServerReceivedRequest={0} requested from {1}:{2}
codeSourceIs=CodeSource for service in ''{0}'' is ''{1}''.
completedServiceDeployment=Completed deployment of service in {0}.
configFile=Configuration file is ''{0}''.
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java?rev=1205741&r1=1205740&r2=1205741&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
Thu Nov 24 07:14:36 2011
@@ -22,9 +22,9 @@ package org.apache.river.container.codeb
import com.sun.jini.logging.Levels;
import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.BindException;
@@ -32,12 +32,14 @@ import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
+import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.apache.commons.vfs.FileObject;
import org.apache.river.container.Init;
import org.apache.river.container.Injected;
import org.apache.river.container.InjectionStyle;
@@ -106,35 +108,33 @@ import org.apache.river.container.work.W
*
*
*/
-
public class ClassServer implements CodebaseHandler {
private static final Logger logger =
Logger.getLogger(ClassServer.class.getName(),
MessageNames.BUNDLE_NAME);
/** Server socket to accept connections on */
private ServerSocket server;
-
- @Injected(style=InjectionStyle.BY_TYPE)
+ @Injected(style = InjectionStyle.BY_TYPE)
private WorkManager workManager = null;
-
@Injected(Strings.CLASS_SERVER_PROPERTIES)
private Properties properties;
+ Map<String, ClassServerCodebaseContext> contexts =
+ new HashMap<String, ClassServerCodebaseContext>();
- List<ClassServerCodebaseContext> contexts=new
ArrayList<ClassServerCodebaseContext>();
-
@Init
public void init() {
try {
establishServerSocket();
workManager.queueTask(TaskClass.SYSTEM_TASK,
Thread.currentThread().getContextClassLoader(),
new Runnable() {
+
@Override
public void run() {
ClassServer.this.run();
}
});
} catch (IOException ex) {
- logger.log(Level.SEVERE, MessageNames.CLASS_SERVER_INIT_FAILED, ex
);
+ logger.log(Level.SEVERE, MessageNames.CLASS_SERVER_INIT_FAILED,
ex);
throw new RuntimeException(ex);
}
}
@@ -142,8 +142,8 @@ public class ClassServer implements Code
private void establishServerSocket() throws IOException, SocketException {
server = new ServerSocket();
server.setReuseAddress(true);
- String initialPortStr=properties.getProperty(Strings.INITIAL_PORT);
- if (initialPortStr==null) {
+ String initialPortStr = properties.getProperty(Strings.INITIAL_PORT);
+ if (initialPortStr == null) {
throw new LocalizedRuntimeException(
MessageNames.BUNDLE_NAME,
MessageNames.MISSING_PROPERTY_ENTRY,
@@ -152,7 +152,7 @@ public class ClassServer implements Code
Strings.INITIAL_PORT
});
}
- int initialPort=Integer.parseInt(initialPortStr);
+ int initialPort = Integer.parseInt(initialPortStr);
try {
server.bind(new InetSocketAddress(initialPort));
} catch (BindException be) {
@@ -166,15 +166,16 @@ public class ClassServer implements Code
rather than setup a loop. Wonder what the ramifications would be?
We'd have more opportunities to end the service task, but possibly more
development effort.
- */
+ */
public void run() {
try {
while (true) {
final Socket connectedSocket = server.accept();
/* Boy, would this be a nice spot to have closures! */
- workManager.queueTask(TaskClass.SYSTEM_TASK,
- Thread.currentThread().getContextClassLoader(),
+ workManager.queueTask(TaskClass.SYSTEM_TASK,
+ Thread.currentThread().getContextClassLoader(),
new Runnable() {
+
@Override
public void run() {
processRequest(connectedSocket);
@@ -207,6 +208,14 @@ public class ClassServer implements Code
return server.getLocalPort();
}
+ /**
+ Returns the hostname that the server is listening to.
+ @return
+ */
+ public String getHost() {
+ return server.getInetAddress().getHostName();
+ }
+
/** Read up to CRLF, return false if EOF */
private static boolean readLine(InputStream in, StringBuffer buf)
throws IOException {
@@ -290,9 +299,9 @@ public class ClassServer implements Code
@Override
public CodebaseContext createContext(String appId) {
// Create a context
- ClassServerCodebaseContext context=new
ClassServerCodebaseContext(appId);
+ ClassServerCodebaseContext context = new
ClassServerCodebaseContext(this, appId);
// Assign a context prefix (url-shortened)
- contexts.add(context);
+ contexts.put(appId, context);
return context;
}
@@ -302,7 +311,6 @@ public class ClassServer implements Code
//destroy the context.
contexts.remove((ClassServerCodebaseContext) context);
}
-
private static ResourceBundle resources;
private static boolean resinit = false;
@@ -342,35 +350,46 @@ public class ClassServer implements Code
}
/** Read specified number of bytes and always close the stream. */
- private byte[] getBytes(InputStream in, long length)
+ private byte[] getBytes(FileObject fo)
throws IOException {
- DataInputStream din = new DataInputStream(in);
- byte[] bytes = new byte[(int) length];
- try {
- din.readFully(bytes);
- } finally {
- din.close();
- }
+ ByteArrayOutputStream out=new ByteArrayOutputStream();
+ byte[] buffer=new byte[1024];
+
+ InputStream in=fo.getContent().getInputStream();
+ int bytesRead=in.read(buffer);
+ while (bytesRead >0) {
+ out.write(buffer, 0, bytesRead);
+ bytesRead=in.read(buffer);
+ }
+ byte[] bytes=out.toByteArray();
+ out.close();
+ in.close();
return bytes;
}
/** Return the bytes of the requested file, or null if not found. */
private byte[] getBytes(String path) throws IOException {
- if ('/' != File.separatorChar) {
- path = path.replace('/', File.separatorChar);
- }
- InputStream is = findInputStreamForPath(path);
- if (is == null) {
+ FileObject fo = findFileObjectForPath(path);
+ if (fo == null) {
return null;
}
- // TODO: Lookup length from contents file.
- int length = 0;
- return getBytes(is, length);
+ return getBytes(fo);
}
- InputStream findInputStreamForPath(String path) {
- //TODO: Implement to lookup registered file.
- return null;
+ FileObject findFileObjectForPath(String path) {
+ /* First path segment is appid. */
+ StringTokenizer tok = new StringTokenizer(path, Strings.SLASH, false);
+ FileObject ret = null;
+ try {
+ String appId = tok.nextToken();
+ String jarName = tok.nextToken();
+ ClassServerCodebaseContext context = contexts.get(appId);
+ ret = context.fileEntries.get(jarName);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, MessageNames.CLASS_SERVER_REJECTED_PATH,
+ path);
+ }
+ return ret;
}
private void writeHeader(DataOutputStream out, byte[] bytes) throws
IOException {
@@ -393,7 +412,7 @@ public class ClassServer implements Code
if (req == null) {
return true;
}
- String[] args = null;
+ String[] args = new String[3];
boolean get = req.startsWith("GET ");
if (!get && !req.startsWith("HEAD ")) {
processBadRequest(args, out);
@@ -405,10 +424,13 @@ public class ClassServer implements Code
if (args != null) {
args[0] = path;
}
+ args[1]=sock.getInetAddress().getHostName();
+ args[2]=Integer.toString(sock.getPort());
+
logger.log(Level.FINER,
get
- ? "{0} requested from {1}:{2}"
- : "{0} probed from {1}:{2}",
+ ? MessageNames.CLASS_SERVER_RECEIVED_REQUEST
+ : MessageNames.CLASS_SERVER_RECEIVED_PROBE,
args);
byte[] bytes;
try {
@@ -441,6 +463,4 @@ public class ClassServer implements Code
}
return false;
}
-
-
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java?rev=1205741&r1=1205740&r2=1205741&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
Thu Nov 24 07:14:36 2011
@@ -19,20 +19,25 @@ package org.apache.river.container.codeb
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.vfs.FileObject;
-import org.apache.river.container.LocalizedRuntimeException;
-import org.apache.river.container.MessageNames;
/**
*
* @author trasukg
*/
public class ClassServerCodebaseContext implements CodebaseContext {
-
+ ClassServer classServer=null;
+
String appId = null;
-
- ClassServerCodebaseContext(String appId) {
+ Map<String, FileObject> fileEntries=new HashMap<String, FileObject>();
+
+ ClassServerCodebaseContext(ClassServer classServer, String appId) {
this.appId = appId;
+ this.classServer=classServer;
}
@Override
@@ -43,14 +48,37 @@ public class ClassServerCodebaseContext
@Override
public void addFile(FileObject file) {
+ /* Add the mapping into our list of objects. */
+ String path=file.getName().getBaseName();
+ fileEntries.put(path, file);
+ /* Force update of the codebase. */
+ codebaseAnnotation=null;
}
+ private List<URL> codebaseAnnotation=null;
+
@Override
public URL[] getCodebaseAnnotation() {
try {
- return new URL[] { new URL("http://unknown.jar") };
+ if (codebaseAnnotation==null) {
+ /*
+ codebase is derived from the list of file objects.
+ */
+ codebaseAnnotation = new ArrayList<URL>();
+ for(String path:fileEntries.keySet()) {
+ codebaseAnnotation.add(new URL(Strings.HTTP_COLON
+ + Strings.SLASH_SLASH
+ + classServer.getHost()
+ + Strings.COLON
+ + classServer.getPort() +
+ Strings.SLASH
+ + appId + Strings.SLASH + path));
+ }
+ }
+ return codebaseAnnotation.toArray(new URL[0]);
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
}
}
+
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/Strings.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/Strings.java?rev=1205741&r1=1205740&r2=1205741&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/Strings.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/Strings.java
Thu Nov 24 07:14:36 2011
@@ -24,6 +24,10 @@ package org.apache.river.container.codeb
public class Strings {
public static final String
CLASS_SERVER_PROPERTIES="class-server.properties",
+ COLON=":",
DUMMY_ANNOTATION="http://www.demo.com/unknown.jar",
- INITIAL_PORT="initialPort";
+ HTTP_COLON="http:",
+ INITIAL_PORT="initialPort",
+ SLASH="/",
+ SLASH_SLASH="//";
}