--- /dev/null
+How to compile the source code.
+
+Run the script "compile.sh" with arguments:
+All options are required except PATH_TO_JAVA, PREFIX and install or remove.
+
+-Dbuild.classes.dir="path to directory where .class files will be saved" \
+-Ddist.dir="path to directory where .jar file will be saved" \
+-Ddist.javadoc.dir="path to directory where documentation will be saved" \
+-Dproject.jobid-api-java="path to directory jobid-api-java" \
+-Dreference.jobid-api-java.jar="path to directory where jobid-api-java.jar is" \
+choose one of these: install or compile \
+PREFIX="path to directory where .so file will be saved" \
+PATH_TO_JAVA="path to directory where java is installed" \
+
+How to run locallogger:
+java -Djava.library.path=/path/to/shared/library -cp "/path/to/jobid-api-java.jar:/path/to/lb-client-java.jar" org.glite.test.Test
+
+If you don't set -Djava.library.path messages will not be send via unix socket but only written to specified file.
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<project name="lb-client-java" default="default" basedir=".">
+ <description>Builds, tests, and runs the project lb-client-java.</description>
+ <import file="nbproject/build-impl.xml"/>
+ <!--
+
+ There exist several targets which are by default empty and which can be
+ used for execution of your tasks. These targets are usually executed
+ before and after some main targets. They are:
+
+ -pre-init: called before initialization of project properties
+ -post-init: called after initialization of project properties
+ -pre-compile: called before javac compilation
+ -post-compile: called after javac compilation
+ -pre-compile-single: called before javac compilation of single file
+ -post-compile-single: called after javac compilation of single file
+ -pre-compile-test: called before javac compilation of JUnit tests
+ -post-compile-test: called after javac compilation of JUnit tests
+ -pre-compile-test-single: called before javac compilation of single JUnit test
+ -post-compile-test-single: called after javac compilation of single JUunit test
+ -pre-jar: called before JAR building
+ -post-jar: called after JAR building
+ -post-clean: called after cleaning build products
+
+ (Targets beginning with '-' are not intended to be called on their own.)
+
+ Example of inserting an obfuscator after compilation could look like this:
+
+ <target name="-post-compile">
+ <obfuscate>
+ <fileset dir="${build.classes.dir}"/>
+ </obfuscate>
+ </target>
+
+ For list of available properties check the imported
+ nbproject/build-impl.xml file.
+
+
+ Another way to customize the build is by overriding existing main targets.
+ The targets of interest are:
+
+ -init-macrodef-javac: defines macro for javac compilation
+ -init-macrodef-junit: defines macro for junit execution
+ -init-macrodef-debug: defines macro for class debugging
+ -init-macrodef-java: defines macro for class execution
+ -do-jar-with-manifest: JAR building (if you are using a manifest)
+ -do-jar-without-manifest: JAR building (if you are not using a manifest)
+ run: execution of project
+ -javadoc-build: Javadoc generation
+ test-report: JUnit report generation
+
+ An example of overriding the target for project execution could look like this:
+
+ <target name="run" depends="lb-client-java-impl.jar">
+ <exec dir="bin" executable="launcher.exe">
+ <arg file="${dist.jar}"/>
+ </exec>
+ </target>
+
+ Notice that the overridden target depends on the jar target and not only on
+ the compile target as the regular run target does. Again, for a list of available
+ properties which you can use, check the target you are overriding in the
+ nbproject/build-impl.xml file.
+
+ -->
+</project>
--- /dev/null
+#!/bin/bash
+cmd1="$1";
+cmd2="$2";
+cmd3="$3";
+cmd4="$4";
+cmd5="$5";
+cmd6="$6";
+cmd7="$7";
+cmd7="$8";
+
+ant $cmd1 $cmd2 $cmd3 $cmd4 $cmd5;
+cd ./src_c
+make $cmd6 $cmd7 $cmd8;
--- /dev/null
+package org.glite.lb.client_java;
+
+/**
+ * Class which escapes \ and new line signs in string which is set as parameter
+ * in constructor
+ *
+ * @author Pavel Piskac (173297@mail.muni.cz)
+ * @version 15. 3. 2008
+ */
+public class CheckedString {
+
+ String checkedString;
+
+ /**
+ * Creates new instance of CheckedString.
+ *
+ * @param checkedString string which will be converted
+ * @throws java.lang.IllegalArgumentException if checkedString is null
+ */
+ public CheckedString(String checkedString) {
+ if (checkedString == null) {
+ throw new IllegalArgumentException("checkedString is null");
+ }
+
+ checkedString = checkedString.replaceAll("[\\\"]", "\\\\\"");
+ checkedString = checkedString.replaceAll("[\n]", "\\\\\\\\n");
+ this.checkedString = checkedString;
+ }
+
+ /**
+ * Gets converted string.
+ *
+ * @return converted string
+ */
+ public String getCheckedString() {
+ return checkedString;
+ }
+
+ /**
+ * Sets string which will be converted.
+ *
+ * @param checkedString string which will be converted.
+ */
+ public void setCheckedString(String checkedString) {
+ checkedString = checkedString.replaceAll("[\\\"]", "\\\\\"");
+ checkedString = checkedString.replaceAll("[\n]", "\\\\\\\\n");
+ this.checkedString = checkedString;
+ }
+
+ /**
+ * Returns converted string.
+ *
+ * @return converted string
+ */
+ public String toString() {
+ return checkedString;
+ }
+
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+import java.net.UnknownHostException;
+import java.util.Calendar;
+import java.util.Random;
+import org.glite.jobid.api_java.Jobid;
+
+/**
+ * Class representing a context for some job
+ *
+ * @author Pavel Piskac (173297@mail.muni.cz)
+ * @version 15. 3. 2008
+ */
+public class Context {
+
+ private int id;
+ private Sources source;
+ private int flag;
+ private String host;
+ private String user;
+ private String prog;
+ private String srcInstance;
+ private Jobid jobid;
+ private SeqCode seqCode;
+ private String message;
+
+ /**
+ * Creates new instance of Context class.
+ */
+ public Context() {
+ }
+
+ /**
+ * Creates new instance of Context class.
+ *
+ * @param id message id, if null, random number is generated
+ * @param source one if paramaters of Sources enumeration
+ * @param flag
+ * @param host host name, if null or "", the name is get from host name of this computer
+ * @param user user name
+ * @param prog if null then is used "egd-wms"
+ * @param srcInstance if null then it is set as ""
+ * @param jobid
+ * @throws java.lang.IllegalArgumentException if source, user or jobid is null
+ * or flag < 0
+ *
+ */
+ public Context(int id,
+ Sources source,
+ int flag,
+ String host,
+ String user,
+ String prog,
+ String srcInstance,
+ Jobid jobid) {
+ if (id < 0) {
+ id = new Random().nextInt();
+ }
+
+ if (source == null)
+ {
+ throw new IllegalArgumentException("Context source");
+ }
+
+ if (flag < 0 || flag > 8)
+ {
+ throw new IllegalArgumentException("Context flag");
+ }
+
+ if (host == null || host.equals(""))
+ {
+ try {
+ host = java.net.InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ex) {
+ System.err.println(ex);
+ }
+ }
+
+ if (user == null)
+ {
+ throw new IllegalArgumentException("Context user");
+ }
+
+ if (prog == null) {
+ prog = new String("edg-wms");
+ }
+
+ if (srcInstance == null)
+ {
+ srcInstance = new String("");
+ }
+
+ if (jobid == null)
+ {
+ throw new IllegalArgumentException("Context jobid");
+ }
+
+ this.id = id;
+ this.source = source;
+ this.flag = flag;
+ this.host = new CheckedString(host).toString();
+ this.user = new CheckedString(user).toString();
+ this.prog = new CheckedString(prog).toString();
+ this.srcInstance = new CheckedString(srcInstance).toString();
+ this.jobid = jobid;
+ }
+
+ /**
+ * Converts Sources enum constants to defined string
+ * @param sourceEnum Sources enum constant
+ * @return String representation of Sources enum constants
+ * @throws IllegalArgumentException if wrong source type is set
+ */
+ private String recognizeSource(Sources sourceEnum) {
+ switch (sourceEnum) {
+ case EDG_WLL_SOURCE_NONE: return "Undefined";
+ case EDG_WLL_SOURCE_USER_INTERFACE: return "UserInterface";
+ case EDG_WLL_SOURCE_NETWORK_SERVER: return "NetworkServer";
+ case EDG_WLL_SOURCE_WORKLOAD_MANAGER: return "WorkloadManager";
+ case EDG_WLL_SOURCE_BIG_HELPER: return "BigHelper";
+ case EDG_WLL_SOURCE_JOB_SUBMISSION: return "JobController";
+ case EDG_WLL_SOURCE_LOG_MONITOR: return "LogMonitor";
+ case EDG_WLL_SOURCE_LRMS: return "LRMS";
+ case EDG_WLL_SOURCE_APPLICATION: return "Application";
+ case EDG_WLL_SOURCE_LB_SERVER: return "LBServer";
+ default: throw new IllegalArgumentException("wrong source type");
+ }
+ }
+
+ public Sources stringToSources(String source) {
+ if (source.equals("EDG_WLL_SOURCE_NONE")) return Sources.EDG_WLL_SOURCE_NONE;
+ if (source.equals("EDG_WLL_SOURCE_USER_INTERFACE")) return Sources.EDG_WLL_SOURCE_USER_INTERFACE;
+ if (source.equals( "EDG_WLL_SOURCE_NETWORK_SERVER")) return Sources.EDG_WLL_SOURCE_NETWORK_SERVER;
+ if (source.equals("EDG_WLL_SOURCE_WORKLOAD_MANAGER")) return Sources.EDG_WLL_SOURCE_WORKLOAD_MANAGER;
+ if (source.equals("EDG_WLL_SOURCE_BIG_HELPER")) return Sources.EDG_WLL_SOURCE_BIG_HELPER;
+ if (source.equals("EDG_WLL_SOURCE_JOB_SUBMISSION")) return Sources.EDG_WLL_SOURCE_JOB_SUBMISSION;
+ if (source.equals("EDG_WLL_SOURCE_LOG_MONITOR")) return Sources.EDG_WLL_SOURCE_LOG_MONITOR;
+ if (source.equals("EDG_WLL_SOURCE_LRMS")) return Sources.EDG_WLL_SOURCE_LRMS;
+ if (source.equals("EDG_WLL_SOURCE_APPLICATION")) return Sources.EDG_WLL_SOURCE_APPLICATION;
+ if (source.equals("EDG_WLL_SOURCE_LB_SERVER")) return Sources.EDG_WLL_SOURCE_LB_SERVER;
+ throw new IllegalArgumentException("wrong source type");
+
+ }
+
+ /**
+ * Creates message prepared to send
+ * @param event event for which is message generated
+ * @throws IllegalArgumentException if event, source, user or job is null
+ * or flag < 0
+ */
+ public void log(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException("Context event");
+ }
+
+ if (source == null)
+ {
+ throw new IllegalArgumentException("Context source");
+ }
+
+ if (flag < 0 || flag > 8)
+ {
+ throw new IllegalArgumentException("Context flag");
+ }
+
+ if (host == null || host.equals(""))
+ {
+ try {
+ host = java.net.InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ex) {
+ System.err.println(ex);
+ }
+ }
+
+ if (prog == null) {
+ prog = new String("edg-wms");
+ }
+
+ if (user == null)
+ {
+ throw new IllegalArgumentException("Context user");
+ }
+
+ if (srcInstance == null)
+ {
+ srcInstance = new String("");
+ }
+
+ if (jobid == null)
+ {
+ throw new IllegalArgumentException("Context jobid");
+ }
+
+ String output;
+ String date = "";
+ String tmp;
+ date = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
+ tmp = String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1);
+ date += "00".substring(0, 2 - tmp.length ()) + tmp;
+ tmp = String.valueOf(Calendar.getInstance().get(Calendar.DATE));
+ date += "00".substring(0, 2 - tmp.length ()) + tmp;
+ tmp = String.valueOf(Calendar.getInstance().get(Calendar.HOUR));
+ date += "00".substring(0, 2 - tmp.length ()) + tmp;
+ tmp = String.valueOf(Calendar.getInstance().get(Calendar.MINUTE));
+ date += "00".substring(0, 2 - tmp.length ()) + tmp;
+ tmp = String.valueOf(Calendar.getInstance().get(Calendar.SECOND));
+ date += "00".substring(0, 2 - tmp.length ()) + tmp;
+ date += ".";
+ tmp = String.valueOf(Calendar.getInstance().get(Calendar.MILLISECOND));
+ String tmp2 = "000".substring(0, 3 - tmp.length ()) + tmp;
+ date += tmp2 + "000000".substring(tmp.length (), 6);
+
+ seqCode.setPardOfSeqCode(flag, seqCode.getPardOfSeqCode(flag)+1);
+
+ output = ("DG.LLLID=" + id +
+ " DG.USER=\"" + user + "\"" +
+ " DATE=" + date +
+ " HOST=\"" + host + "\"" +
+ " PROG=" + prog +
+ " LVL=SYSTEM" +
+ " DG.PRIORITY=0" +
+ " DG.SOURCE=\"" + recognizeSource(source) + "\"" +
+ " DG.SRC_INSTANCE=\"" + srcInstance + "\"" +
+ " DG.EVNT=\"" + event.getEventType() + "\"" +
+ " DG.JOBID=\"" + jobid + "\"" +
+ " DG.SEQCODE=\"" + seqCode + "\"" +
+ event.ulm());
+
+ this.message = output;
+ }
+
+ /**
+ * Return flag which represents which part of sequence code will be changes
+ *
+ * @return flag
+ */
+ public int getFlag() {
+ return flag;
+ }
+
+ /**
+ * Set flag which represents which part of sequence code will be changes
+ *
+ * @param flag
+ * @throws java.lang.IllegalArgumentException if flag is lower than 0
+ */
+ public void setFlag(int flag) {
+ if (flag < 0 || flag > 8)
+ {
+ throw new IllegalArgumentException("Context flag");
+ }
+
+ this.flag = flag;
+ }
+
+ /**
+ * Returns host name
+ *
+ * @return host name
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * Sets host name
+ * @param host host name
+ * @throws java.lang.IllegalArgumentException if host is null
+ */
+ public void setHost(String host) {
+ if (host == null)
+ {
+ throw new IllegalArgumentException("Context host");
+ }
+
+ this.host = host;
+ }
+
+ /**
+ * Gets message id.
+ *
+ * @return message id
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Sets message id.
+ *
+ * @param id message id
+ * @throws java.lang.IllegalArgumentException if id is lower than 0
+ */
+ public void setId(int id) {
+ if (id < 0)
+ {
+ throw new IllegalArgumentException("Context id");
+ }
+ this.id = id;
+ }
+
+ /**
+ * Gets jobid.
+ *
+ * @return jobid
+ */
+ public Jobid getJobid() {
+ return jobid;
+ }
+
+ /**
+ * Sets jobid.
+ *
+ * @param jobid
+ * @throws java.lang.IllegalArgumentException if jobid is null
+ */
+ public void setJobid(Jobid jobid) {
+ if (jobid == null)
+ {
+ throw new IllegalArgumentException("Context jobid");
+ }
+
+ this.jobid = jobid;
+ }
+
+ /**
+ * Gets message which is prepared to send.
+ * @return message
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Gets prog.
+ * @return prog
+ */
+ public String getProg() {
+ return prog;
+ }
+
+ /**
+ * Sets prog, if prog is null then is set default value "edg-wms"
+ * @param prog
+ */
+ public void setProg(String prog) {
+ if (prog == null) {
+ prog = new String("edg-wms");
+ }
+
+ this.prog = (new CheckedString(prog)).toString();
+ }
+
+ /**
+ * Gets sequence code.
+ *
+ * @return sequence code
+ */
+ public SeqCode getSeqCode() {
+ return seqCode;
+ }
+
+ /**
+ * Sets sequence code.
+ * @param seqCode sequence code
+ * @throws java.lang.IllegalArgumentException if seqCode is null
+ */
+ public void setSeqCode(SeqCode seqCode) {
+ if (seqCode == null) {
+ throw new IllegalArgumentException("Context seqCode");
+ }
+
+ this.seqCode = seqCode;
+ }
+
+ /**
+ * Gets source.
+ * @return source
+ */
+ public Sources getSource() {
+ return source;
+ }
+
+ /**
+ * Sets source
+ * @param source source
+ * @throws java.lang.IllegalArgumentException if source is null
+ */
+ public void setSource(Sources source) {
+ if (source == null)
+ {
+ throw new IllegalArgumentException("Context source");
+ }
+
+ this.source = source;
+ }
+
+ /**
+ * Gets srcInstance.
+ * @return srcInstance
+ */
+ public String getSrcInstance() {
+ return srcInstance;
+ }
+
+ /**
+ * Sets srcInstace, if srcInstace null then is set "".
+ * @param srcInstance srcInstance
+ */
+ public void setSrcInstance(String srcInstance) {
+ if (srcInstance == null)
+ {
+ srcInstance = new String("");
+ }
+
+ this.srcInstance = new CheckedString(srcInstance).toString();
+ }
+
+ /**
+ * Gets user name.
+ * @return user name
+ */
+ public String getUser() {
+ return user;
+ }
+
+ /**
+ * Sets user name.
+ * @param user user name
+ * @throws java.lang.IllegalArgumentException if user is null
+ */
+ public void setUser(String user) {
+ if (user == null)
+ {
+ throw new IllegalArgumentException("Context user");
+ }
+
+ this.user = (new CheckedString(user)).toString();
+ }
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import org.glite.jobid.api_java.Jobid;
+
+/**
+ * Class which is used to send messages to inter-logger using unix socket.
+ *
+ * @author Pavel Piskac (173297@mail.muni.cz)
+ */
+public class ContextIL extends Context {
+
+ private String pathToSocket;
+ private String pathToNativeLib;
+ private String prefix;
+ private int repeatWriteToFile = 5;
+ private int connAttempts = 3;
+ private int timeout = 3;
+ private Boolean useUnixSocket = true;
+
+ //navod http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jni.html
+ //native method which is written in C and imported to Java
+ native int sendToSocket(String socket_path,
+ long filepos,
+ String msg,
+ int msg_size,
+ int conn_attempts,
+ int timeout);
+
+ /**
+ * Creates new instance of ContextIL.
+ */
+ public ContextIL() {
+ }
+
+ /**
+ * Creates new instance of ContextIL.
+ *
+ * @param pathToSocket path to unix socket
+ * @param prefix path where are stored messages
+ */
+ public ContextIL(String pathToSocket, String prefix) {
+ this.prefix = new CheckedString(prefix).toString();
+ this.pathToSocket = new CheckedString(pathToSocket).toString();
+ }
+
+ /**
+ * Creates new instance of ContextIL.
+ *
+ * @param id message id, if null, random number is generated
+ * @param source one if paramaters of Sources enumeration
+ * @param flag
+ * @param host host name, if null or "", the name is get from host name of this computer
+ * @param user user name
+ * @param prog if null then is used "egd-wms"
+ * @param srcInstance if null then it is set as ""
+ * @param jobid jobid
+ * @param path path to unix socket
+ * @param prefix path where are stored messages
+ * @throws java.lang.IllegalArgumentException if source, user, jobid, prefix
+ * or path is null or flag < 0
+ */
+ public ContextIL(int id,
+ Sources source,
+ int flag,
+ String host,
+ String user,
+ String prog,
+ String srcInstance,
+ Jobid jobid,
+ String path,
+ String prefix) {
+
+ super(id, source, flag, host, user, prog, srcInstance, jobid);
+
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextIL prefix");
+ }
+
+ if (path == null) {
+ throw new IllegalArgumentException("ContextIL path");
+ }
+
+ this.prefix = new CheckedString(prefix).toString();
+ this.pathToSocket = new CheckedString(pathToSocket).toString();
+ }
+
+ /**
+ * Writes message to a file and returns original size of this file
+ *
+ * @param prefix file path
+ * @param message message which will be written
+ * @return size of the file before writing the data
+ */
+ private Long writeToFile(String prefix, String message) {
+ FileWriter fileWriter = null;
+ Long fileLength = null;
+ RandomAccessFile raf = null;
+ FileLock fileLock = null;
+ File file;
+
+ for (int i = 0; i < repeatWriteToFile; i++) {
+ try {
+ file = new File(prefix);
+ raf = new RandomAccessFile(file, "rw");
+ FileChannel fileChannel = raf.getChannel();
+
+ fileLock = fileChannel.tryLock();
+ if (fileLock != null) {
+ if (!file.exists()) {
+ continue;
+ }
+ fileLength = raf.length();
+ fileWriter = new FileWriter(file, true);
+ //true means append data at the end of file
+
+ BufferedWriter bufferedFileWriter = new BufferedWriter(fileWriter);
+
+ bufferedFileWriter.write(message + '\n');
+ bufferedFileWriter.flush();
+
+ if (file.exists()) {
+ break;
+ }
+ }
+ } catch (FileNotFoundException ex) {
+ System.err.println(ex);
+ } catch (IOException ex) {
+ System.err.println(ex);
+ } catch (Exception ex) {
+ System.err.println(ex);
+ } finally {
+ if (fileLock != null) {
+ try {
+ fileLock.release();
+ } catch (IOException ex) {
+ System.err.println(ex);
+ }
+ }
+
+ try {
+ raf.close();
+ } catch (IOException ex) {
+ System.err.println(ex);
+ } catch (NullPointerException ex) {
+ System.err.println(ex);
+ }
+ }
+ }
+
+ return fileLength;
+ }
+
+ /**
+ * Writes file position and message to specified socket.
+ *
+ * @param pathToSocket path to unix socket
+ * @param fileSize size of the file before new message was written there
+ * @param message message which will be send
+ * @param conn_attempts count of connection attempts
+ * @param time_out connection timeout
+ */
+ private void writeToSocket(String pathToSocket,
+ long fileSize,
+ String message) {
+
+ if (useUnixSocket) {
+ try {
+ System.loadLibrary("sendviasocket");
+ message += '\n';
+ sendToSocket(pathToSocket,
+ fileSize,
+ message,
+ message.length(),
+ connAttempts,
+ timeout);
+
+ } catch (UnsatisfiedLinkError ex) {
+ useUnixSocket = false;
+ System.err.println(ex);
+ }
+ }
+ }
+
+ /**
+ * Writes event message to the file and socket.
+ *
+ * @param event event
+ * @throws java.lang.IllegalArgumentException if event, prefix or path
+ */
+ @Override
+ public void log(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException("ContextIL event");
+ }
+
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextIL prefix");
+ }
+
+ if (pathToSocket == null || pathToSocket.equals("")) {
+ pathToSocket = new String("");
+ useUnixSocket = false;
+ }
+
+ if (pathToNativeLib == null || pathToNativeLib.equals("")) {
+ pathToNativeLib = new String("");
+ useUnixSocket = false;
+ }
+
+ super.log(event);
+ String message = super.getMessage();
+
+ Long fileLength = writeToFile(prefix, message);
+
+ writeToSocket(pathToSocket, fileLength, message);
+ }
+
+ /**
+ * Gets path to socket.
+ *
+ * @return pathToSocket to socket
+ */
+ public String getPathToSocket() {
+ return pathToSocket;
+ }
+
+ /**
+ * Sets path to socket.
+ *
+ * @param pathToSocket path to socket
+ * @throws java.lang.IllegalArgumentException if path is null
+ */
+ public void setPathToSocket(String pathToSocket) {
+ if (pathToSocket == null) {
+ throw new IllegalArgumentException("ContextIL pathToSocket");
+ }
+
+ this.pathToSocket = new CheckedString(pathToSocket).toString();
+ }
+
+ /**
+ * Gets path to nativelib file which is needed to send messages via unix socket
+ *
+ * @return pathToNativeLib to native library (libnativelib.so)
+ */
+ public String getPathToNativeLib() {
+ return pathToNativeLib;
+ }
+
+ /**
+ * Sets path to nativelib file which is needed to send messages via unix socket
+ * @param pathToNativeLib path to shared library (libnativelib.so)
+ */
+ public void setPathToNativeLib(String pathToNativeLib) {
+ if (pathToNativeLib == null) {
+ throw new IllegalArgumentException("ContextIL pathToNativeLib");
+ }
+
+ this.pathToNativeLib = pathToNativeLib;
+ }
+
+ /**
+ * Gets path where are stored messages.
+ *
+ * @return path where are stored messages
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Sets path where are stored messages.
+ *
+ * @param prefix path where are stored messages
+ */
+ public void setPrefix(String prefix) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextIL prefix");
+ }
+
+ this.prefix = new CheckedString(prefix).toString();
+ }
+
+ /**
+ * Gets count of repeated write to file if some exception is thrown.
+ *
+ * @return count of repeated write to file
+ */
+ public int getRepeatWriteToFile() {
+ return repeatWriteToFile;
+ }
+
+ /**
+ * Sets count of repeated write to file if some exception is thrown.
+ *
+ * @param repeatWriteToFile count of repeated write to file
+ */
+ public void setRepeatWriteToFile(int repeatWriteToFile) {
+ if (repeatWriteToFile < 1) {
+ throw new IllegalArgumentException("ContextIL repeatWriteToFile");
+ }
+
+ this.repeatWriteToFile = repeatWriteToFile;
+ }
+
+ /**
+ * Gets count of connection attempts which is used while sending the message via unix socket.
+ *
+ * @return count of connection attempts
+ */
+ public int getConnAttempts() {
+ return connAttempts;
+ }
+
+ /**
+ * Sets count of connection attempts while sending the message via unix socket.
+ *
+ * @param connAttempts count of connection attempts
+ */
+ public void setConnAttempts(int connAttempts) {
+ if (connAttempts < 1) {
+ throw new IllegalArgumentException("ContextIL conn_attempts");
+ }
+
+ this.connAttempts = connAttempts;
+ }
+
+ /**
+ * Gets timeout which is used while sending the message via unix socket.
+ *
+ * @return timeout
+ */
+ public int getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Sets timeout which is used while sending the message via unix socket.
+ *
+ * @param timeout timeout
+ */
+ public void setTimeout(int timeout) {
+ if (timeout < 1) {
+ throw new IllegalArgumentException("ContextIL time_out");
+ }
+
+ this.timeout = timeout;
+ }
+
+ public Boolean getUseUnixSocket() {
+ return useUnixSocket;
+ }
+
+ public void setUseUnixSocket(Boolean useUnixSocket) {
+ if (useUnixSocket == null) {
+ throw new IllegalArgumentException("ContextIL useUnixSocket");
+ }
+
+ this.useUnixSocket = useUnixSocket;
+ }
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.util.ArrayList;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.glite.jobid.api_java.Jobid;
+
+/**
+ *
+ * @author xpiskac
+ */
+public class ContextProxy extends Context {
+
+ private String address;
+ private int port;
+ private String prefix;
+ private int repeatWriteToFile = 5;
+ private int timeout = 30000;
+ private String pathToCertificate;
+ private String password;
+
+ public ContextProxy() {
+ }
+
+ public ContextProxy(String address, int port, String prefix) {
+ this.prefix = new CheckedString(prefix).toString();
+ this.address = new CheckedString(address).toString();
+ this.port = port;
+ }
+
+ public ContextProxy(int id,
+ Sources source,
+ int flag,
+ String host,
+ String user,
+ String prog,
+ String srcInstance,
+ Jobid jobid,
+ String address,
+ int port,
+ String prefix) {
+
+ super(id, source, flag, host, user, prog, srcInstance, jobid);
+
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextProxy prefix");
+ }
+ if (address == null) {
+ throw new IllegalArgumentException("ContextProxy socket");
+ }
+ if (port < 0) {
+ throw new IllegalArgumentException("ContextProxy port");
+ }
+
+ this.prefix = new CheckedString(prefix).toString();
+ this.address = new CheckedString(address).toString();
+ }
+
+ /**
+ * Writes message to a file and returns size of this file before writing the
+ * data
+ * @param prefix file path
+ * @param message message which will be written
+ * @return size of the file before writing the data
+ */
+ private Long writeToFile(String prefix, String message) {
+ FileWriter fileWriter = null;
+ Long fileLength = null;
+ RandomAccessFile raf = null;
+ FileLock fileLock = null;
+ File file;
+
+ for (int i = 0; i < repeatWriteToFile; i++) {
+ try {
+ file = new File(prefix);
+ raf = new RandomAccessFile(file, "rw");
+ FileChannel fileChannel = raf.getChannel();
+
+ fileLock = fileChannel.tryLock();
+ if (fileLock != null) {
+ if (!file.exists()) {
+ continue;
+ }
+ fileLength = raf.length();
+ fileWriter = new FileWriter(file, true);
+ //true means append data to the end of file
+
+ BufferedWriter bufferedFileWriter = new BufferedWriter(fileWriter);
+
+ bufferedFileWriter.write(message + '\n');
+ bufferedFileWriter.flush();
+
+ if (file.exists()) {
+ break;
+ }
+ }
+ } catch (FileNotFoundException ex) {
+ System.err.println(ex);
+ } catch (IOException ex) {
+ System.err.println(ex);
+ } catch (Exception ex) {
+ System.err.println(ex);
+ } finally {
+ if (fileLock != null) {
+ try {
+ fileLock.release();
+ } catch (IOException ex) {
+ System.err.println(ex);
+ }
+ }
+
+ try {
+ raf.close();
+ } catch (IOException ex) {
+ System.err.println(ex);
+ }
+ }
+ }
+
+ return fileLength;
+ }
+
+ private void writeToSocket(String address, int port, int timeout, long fileSize, String message) {
+ // From http://sci.civ.zcu.cz/java/lbexample.zip ExampleSSLSocketFactory.java
+ SSLSocketFactory sslFactory = null;
+ try {
+ SSLSocket socket = (SSLSocket) sslFactory.createSocket();
+ //enable only SSLv3
+ socket.setEnabledProtocols(new String[]{"SSLv3"}); // SSLv2Hello, SSLv3,TLSv1
+ //enable only ciphers without RC4 (some bug in JSSE?)
+ String[] ciphers = socket.getEnabledCipherSuites();
+ ArrayList<String> al = new ArrayList<String>(ciphers.length);
+ for (int i = 0; i < ciphers.length; i++) {
+ if (ciphers[i].indexOf("RC4") == -1) al.add(ciphers[i]);
+ }
+ socket.setEnabledCipherSuites((String [])al.toArray(new String[al.size()]));
+ //connect as client
+ socket.setUseClientMode(true);
+ socket.setSoTimeout(timeout); //read timeout
+ socket.connect(new InetSocketAddress(address, port), timeout); //connect timeout
+ PrintWriter osw =
+ new PrintWriter(socket.getOutputStream(), true);
+ osw.println(fileSize);
+ osw.println(message);
+ osw.close();
+ socket.close();
+ } catch (UnknownHostException ex) {
+ System.err.println("unknown host " + ex);
+ } catch (IOException ex) {
+ System.err.println("io exception " + ex);
+ }
+ }
+
+ @Override
+ public void log(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException("ContextProxy event");
+ }
+
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextProxy prefix");
+ }
+
+ if (address == null) {
+ throw new IllegalArgumentException("ContextProxy socket");
+ }
+
+ if (port < 0) {
+ throw new IllegalArgumentException("ContextProxy port");
+ }
+
+ super.log(event);
+ String message = super.getMessage();
+
+ Long fileSize = writeToFile(prefix, message);
+
+ //writeToSocket(address, port, timeout, fileSize, message);
+
+ //SSLSend sslSend = new SSLSend(keyStoreSender, password, address,
+ // port, timeout, fileSize, message);
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextProxy address");
+ }
+
+ this.address = new CheckedString(address).toString();
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ if (port < 0) {
+ throw new IllegalArgumentException("ContextProxy port");
+ }
+ this.port = port;
+ }
+
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("ContextProxy prefix");
+ }
+
+ this.prefix = new CheckedString(prefix).toString();
+ }
+
+ public int getRepeatWriteToFile() {
+ return repeatWriteToFile;
+ }
+
+ public void setRepeatWriteToFile(int repeatWriteToFile) {
+ if (repeatWriteToFile < 1) {
+ throw new IllegalArgumentException("ContextProxy repeatWriteToFile");
+ }
+
+ this.repeatWriteToFile = repeatWriteToFile;
+ }
+
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ if (timeout < 0) {
+ throw new IllegalArgumentException("ContextProxy timout");
+ }
+ this.timeout = timeout;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ if (password == null) {
+ throw new IllegalArgumentException("ContextProxy password");
+ }
+
+ this.password = password;
+ }
+
+ public String getPathToCertificate() {
+ return pathToCertificate;
+ }
+
+ public void setPathToCertificate(String pathToCertificate) {
+ if (pathToCertificate == null) {
+ throw new IllegalArgumentException("ContextProxy pathToCertificate");
+ }
+
+ this.pathToCertificate = pathToCertificate;
+ }
+
+
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+/**
+ * Abstract class which serves as base for all events.
+ *
+ * @author Pavel Piskac (173297@mail.muni.cz)
+ */
+public abstract class Event {
+
+ /**
+ * When implemented, this method returns string which is specific for each event.
+ *
+ * @return specific string
+ */
+ public abstract String ulm();
+
+ /**
+ * When implemented, this method returns name of event type.
+ *
+ * @return name of event
+ */
+ public abstract String getEventType();
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+/**
+ * Class which represents event "running".
+ *
+ * @author Pavel Piskac (173297@mail.muni.cz)
+ */
+public class Running extends Event {
+
+ private String node;
+
+ /**
+ * Creates new instance.
+ */
+ public Running() {
+ }
+
+ /**
+ * Creates new instance, where is set variable node.
+ * @param node node
+ */
+ public Running(String node) {
+ if (node == null) {
+ node = new String("");
+ }
+
+ this.node = node;
+ }
+
+ /**
+ * Returns part of message, which will be joined to the of the message.
+ * Its format is " DG.RUNNING.NODE=\"" + node + "\""
+ * @return part of message which is specific for event running
+ */
+ public String ulm() {
+ return (" DG.RUNNING.NODE=\"" + node + "\"");
+ }
+
+ /**
+ * Returns event type specific for event running ("Running").
+ *
+ * @return event type
+ */
+ public String getEventType() {
+ return "Running";
+ }
+
+ /**
+ * Gets node.
+ *
+ * @return node
+ */
+ public String getNode() {
+ return node;
+ }
+
+ /**
+ * Sets node, if node is null then it is "" set.
+ * @param node
+ */
+ public void setNode(String node) {
+ if (node == null) {
+ node = new String("");
+ }
+
+ this.node = new CheckedString(node).toString();
+ }
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+/**
+ *
+ * @author xpiskac
+ */
+public class SeqCode {
+
+ private int[] seqCode = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ public SeqCode() {
+ }
+
+ public int[] getSeqCode() {
+ return seqCode;
+ }
+
+ public void setSeqCode(int[] seqCode) {
+ this.seqCode = seqCode;
+ }
+
+ public int getPardOfSeqCode(int part) {
+ if (part < 0 || part > 9) {
+ throw new IllegalArgumentException("part");
+ }
+
+ return seqCode[part];
+ }
+
+ public void setPardOfSeqCode(int part, int value) {
+ if (part < 0 || part > 9) {
+ throw new IllegalArgumentException("part");
+ }
+
+ seqCode[part] = value;
+ }
+
+ public String toString() {
+ String tmp = Integer.toString(seqCode[0]);
+ String output = "UI=";
+ output += "000000".substring(0, 6 - tmp.length ()) + tmp;
+ output += ":";
+ output += "NS=";
+ tmp = Integer.toString(seqCode[1]);
+ output += "0000000000".substring(0, 10 - tmp.length ()) + tmp;
+ output += ":";
+ output += "WM=";
+ tmp = Integer.toString(seqCode[2]);
+ output += "0000000000".substring(0, 6 - tmp.length ()) + tmp;
+ output += ":";
+ output += "BH=";
+ tmp = Integer.toString(seqCode[3]);
+ output += "0000000000".substring(0, 10 - tmp.length ()) + tmp;
+ output += ":";
+ output += "JSS=";
+ tmp = Integer.toString(seqCode[4]);
+ output += "0000000000".substring(0, 6 - tmp.length ()) + tmp;
+ output += ":";
+ output += "LM=";
+ tmp = Integer.toString(seqCode[5]);
+ output += "0000000000".substring(0, 6 - tmp.length ()) + tmp;
+ output += ":";
+ output += "LMRS=";
+ tmp = Integer.toString(seqCode[6]);
+ output += "0000000000".substring(0, 6 - tmp.length ()) + tmp;
+ output += ":";
+ output += "APP=";
+ tmp = Integer.toString(seqCode[7]);
+ output += "0000000000".substring(0, 6 - tmp.length ()) + tmp;
+ output += ":";
+ output += "LBS=";
+ tmp = Integer.toString(seqCode[8]);
+ output += "0000000000".substring(0, 6 - tmp.length ()) + tmp;
+ return output;
+ }
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+/**
+ * Enum which represents type if sources.
+ *
+ * @author Pavel Piskac (173297@mail.muni.cz)
+ */
+public enum Sources {
+ EDG_WLL_SOURCE_NONE, /* uninitialized value */
+ EDG_WLL_SOURCE_USER_INTERFACE,
+ EDG_WLL_SOURCE_NETWORK_SERVER,
+ EDG_WLL_SOURCE_WORKLOAD_MANAGER,
+ EDG_WLL_SOURCE_BIG_HELPER,
+ EDG_WLL_SOURCE_JOB_SUBMISSION,
+ EDG_WLL_SOURCE_LOG_MONITOR,
+ EDG_WLL_SOURCE_LRMS,
+ EDG_WLL_SOURCE_APPLICATION,
+ EDG_WLL_SOURCE_LB_SERVER
+}
--- /dev/null
+package org.glite.lb.client_java;
+
+/**
+ *
+ * @author xpiskac
+ */
+public class Transfer extends Event {
+
+ private String destination;
+ private String destHostname;
+ private String destInstance;
+ private String jobDescription;
+ private String result;
+ private String reason;
+ private String destJobid;
+
+ public Transfer() {
+ }
+
+ public Transfer (String destination,
+ String destHostname,
+ String destInstance,
+ String jobDescription,
+ String result,
+ String reason,
+ String destJobid) {
+
+ this.destination = destination;
+ this.destHostname = destHostname;
+ this.destInstance = destInstance;
+ this.jobDescription = jobDescription;
+ this.result = result;
+ this.reason = reason;
+ this.destJobid = destJobid;
+ }
+
+ public String ulm() {
+ return null; //zatim neimplementovano
+ }
+
+ public String getEventType() {
+ return "Transfer";
+ }
+
+ public String getDestHostname() {
+ return destHostname;
+ }
+
+ public void setDestHostname(String destHostname) {
+ this.destHostname = destHostname;
+ }
+
+ public String getDestInstance() {
+ return destInstance;
+ }
+
+ public void setDestInstance(String destInstance) {
+ this.destInstance = destInstance;
+ }
+
+ public String getDestJobid() {
+ return destJobid;
+ }
+
+ public void setDestJobid(String destJobid) {
+ this.destJobid = destJobid;
+ }
+
+ public String getDestination() {
+ return destination;
+ }
+
+ public void setDestination(String destination) {
+ this.destination = destination;
+ }
+
+ public String getJobDescription() {
+ return jobDescription;
+ }
+
+ public void setJobDescription(String jobDescription) {
+ this.jobDescription = jobDescription;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public void setResult(String result) {
+ this.result = result;
+ }
+}
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.glite.test;
+
+import java.util.Random;
+import org.glite.jobid.api_java.Jobid;
+import org.glite.lb.client_java.ContextIL;
+import org.glite.lb.client_java.Running;
+import org.glite.lb.client_java.SeqCode;
+
+/**
+ *
+ * @author xpiskac
+ */
+public class Test {
+
+ public static void main(String[] args) {
+
+ //how Jobid class works
+ /* //unique part is automatically generated
+ Jobid jobid = new Jobid("https://somewhere.cz", 5000);
+ System.out.println("bkserver "+ jobid.getBkserver());
+ System.out.println("port "+ jobid.getPort());
+ System.out.println("unique "+ jobid.getUnique());
+ System.out.println("-------------------");
+
+ //unique part is set by user
+ Jobid jobid2 = new Jobid("https://somewhere.cz", 5000, "my_unique_part");
+ System.out.println("bkserver "+ jobid2.getBkserver());
+ System.out.println("port "+ jobid2.getPort());
+ System.out.println("unique "+ jobid2.getUnique());
+ System.out.println("-------------------");
+
+ //whole jobid is set by user and then parsed
+ Jobid jobid3 = new Jobid("https://somewhere.cz:5000/my_unique_part");
+ System.out.println("bkserver "+ jobid3.getBkserver());
+ System.out.println("port "+ jobid3.getPort());
+ System.out.println("unique "+ jobid3.getUnique());
+ System.out.println("-------------------");
+
+ //each part is set separately
+ Jobid jobid4 = new Jobid();
+ jobid4.setBkserver("https://somewhere.cz");
+ jobid4.setPort(5000);
+ jobid4.setUnique("my_unique_part");
+ System.out.println("bkserver "+ jobid4.getBkserver());
+ System.out.println("port "+ jobid4.getPort());
+ System.out.println("unique "+ jobid4.getUnique());
+ System.out.println("-------------------");
+
+ */
+ if (args.length == 0) {
+ System.out.println("How to use test class:\n" +
+ "you have to set 10 arguments in this order, if the choice is optional \"\" or text has to be set:\n" +
+ "1. jobid in format \"https://somewhere:port/unique_part\" (required)\n" +
+ "2. path to shared library written in c to be able to send messages via unix socket (optional)\n" +
+ "3. source, enum constant from class Sources (required)\n" +
+ "4. flag determines which part of sequence code will be increased\n" +
+ "5. host name, if it is \"\" then is set name of the computer where is test class running (optional)\n" +
+ "6. user name (required)\n" +
+ "7. PID of running process (optional)\n" +
+ "8. path to directory where will be saved files with events for each job (required)\n" +
+ "9. path to unix socket (required if path to shared library is set)\n" +
+ "10. description for event in this case event running (optional)\n");
+ } else {
+ /* Create new instance of jobid, you can use other constructors too (see org.glite.jobid.api_java.Jobid.java)
+ * Examples:
+ * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz:9000/paja6_test2");
+ * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz", 9000, "paja6_test2");
+ * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz", 9000); //unique part is automatically generated
+ * Jobid jobid = new Jobid();
+ * jobid.setBkserver("https://skurut68-2.cesnet.cz");
+ * jobid.setPort(9000);
+ * jobid.setUnique("paja6_test2");
+ */
+ Jobid jobid = new Jobid(args[0]);
+
+ /* Create sequence code
+ * Example:
+ * SeqCode seqCode = new SeqCode();
+ * Then you can set some parts
+ * Example:
+ * seqCode.setPardOfSeqCode(0, 95);
+ * or whole sequence number
+ * Example:
+ * int[] seqCodeArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ * seqCode.setSeqCode(seqCodeArray);
+ */
+ SeqCode seqCode = new SeqCode();
+
+ /* Choose type of sending a log messages (at this time is implemented only ContextIL class)
+ * You can choose from some constructors (see org.glite.lb.client_java.ContextIL class)
+ */
+ ContextIL ctx = new ContextIL();
+
+ /* If you chose emtpy ContextIL constructor you have to set some attributes.
+ * One of them is pathToNativeLib which sais where java can find shared library written in c.
+ * Example: ctx.setPathToNativeLib("/home/paja6/locallogger/build/classes/org/glite/lb/");
+ */
+ ctx.setPathToNativeLib(args[1]);
+
+ /* Id of the message is some random unique number.
+ */
+ ctx.setId(new Random().nextInt(99999999));
+
+ /* Source indicates source of the message, it is constant from org.glite.lb.client_java.Sources class
+ * Example: ctx.setSource(ctx.stringToSources("EDG_WLL_SOURCE_LRMS"));
+ */
+ ctx.setSource(ctx.stringToSources(args[2]));
+
+ /* Flag tells which part of the sequence number will be increased. It is a number in range from 0 to 8
+ * Example: ctx.setFlag(0);
+ */
+ ctx.setFlag(new Integer(args[3]));
+
+ /* Name of the computer where is locallogger running
+ * Example: ctx.setHost("pelargir.ics.muni.cz");
+ */
+ ctx.setHost(args[4]);
+
+ /* Name of the user who owns the job.
+ * Example: ctx.setUser("Pavel Piskac");
+ */
+ ctx.setUser(args[5]);
+
+ /* TODO co to vlastne znamena?
+ * Mostly "" is set
+ * Example: ctx.setSrcInstance("");
+ */
+ ctx.setSrcInstance(args[6]);
+
+ /* Set the jobid for the context.
+ */
+ ctx.setJobid(jobid);
+
+ /* Set the jobid for the context.
+ */
+ ctx.setSeqCode(seqCode);
+
+ /* Number of connection attempts while sending the message via unix socket.
+ * Default value is 3 but you can change it.
+ */
+ ctx.setConnAttempts(5);
+
+ /* Timeout in seconds for the connection while sending the message via unix socket.
+ * Default value is 3 but you can change it.
+ */
+ ctx.setTimeout(2);
+
+ /* Path to directory where will be saved files with logs until inter-logger sends
+ * the content.
+ * Example: ctx.setPrefix("/home/paja6/tmp/dglog." + jobid.getUnique());
+ */
+ ctx.setPrefix(args[7]);
+
+ /* Path to unix socket.
+ * Example: ctx.setPathToSocket("/home/paja6/tmp/il.sock");
+ */
+ ctx.setPathToSocket(args[8]);
+
+ /* Create new instance of the event which will be logged.
+ */
+ Running running = new Running();
+
+ /* Set some description for the event.
+ * Example: running.setNode("worker node");
+ */
+ running.setNode(args[9]);
+
+ /* And now is the context and event prepared to work.
+ *
+ */
+ ctx.log(running);
+ }
+ }
+}
--- /dev/null
+CC=gcc
+PREFIX=${HOME}/tmp
+PATH_TO_JAVA=${JAVA_HOME}
+
+LIB=libglite_lb_sendviasocket.la
+OBJ=send_via_socket.lo
+
+compile: ${LIB}
+
+${LIB}: ${OBJ}
+ libtool --mode=link ${CC} -rpath ${PREFIX}/lib -o $@ ${OBJ}
+
+%.lo: %.c
+ libtool --mode=compile ${CC} -I${PATH_TO_JAVA}/include -I${PATH_TO_JAVA}/include/linux -c $<
+
+install: compile
+ -mkdir -p ${PREFIX}/lib
+ libtool --mode=install install -m 755 ${LIB} ${PREFIX}/lib
--- /dev/null
+#include <jni.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <pwd.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+/**
+ *----------------------------------------------------------------------
+ * Open a GSS connection to local-logger, send already formatted ULM string
+ * and get answer back from local-logger
+ * \brief connect to local-logger, send message and get answer back
+ * \param[in,out] ctx context to work with,
+ * \param[in] logline formated ULM string
+ *----------------------------------------------------------------------
+ */
+int edg_wll_DoLogEvent(
+ edg_wll_Context ctx,
+ edg_wll_LogLine logline)
+{
+ int ret = 0, answer = EAGAIN;
+ int conn;
+
+ edg_wll_ResetError(ctx);
+ memset(&conn,0,sizeof(conn));
+
+ /* connect to local-logger */
+ if ((ret = edg_wll_log_connect(ctx,&conn))) {
+ fprintf(stderr, "edg_wll_log_connect error");
+ goto edg_wll_DoLogEvent_end;
+ }
+
+ /* send message */
+ if ((ret = edg_wll_log_write(ctx,conn,logline)) == -1) {
+ fprintf(stderr, "edg_wll_log_write error");
+ goto edg_wll_DoLogEvent_end;
+ }
+
+ /* get answer */
+ if ((ret = edg_wll_log_read(ctx,conn)) == -1) {
+ fprintf(stderr, "edg_wll_log_read error");
+ } else {
+ answer = edg_wll_Error(ctx, NULL, NULL);
+ }
+
+edg_wll_DoLogEvent_end:
+ if (ret) edg_wll_log_close(ctx,conn);
+
+ return 0;
+}
+
+/**
+ *----------------------------------------------------------------------
+ * connect to locallogger
+ *----------------------------------------------------------------------
+ */
+int edg_wll_log_connect(edg_wll_Context ctx, int *conn)
+{
+ int ret, answer=0, index;
+ char *my_subject_name = NULL;
+ edg_wll_GssStatus gss_stat;
+
+ //edg_wll_ResetError(ctx);
+ //edg_wll_poolLock();
+
+ /* check if connection already in pool */
+ if ( (index = ConnectionIndex(ctx, ctx->p_destination, ctx->p_dest_port)) == -1 ) {
+ if (ctx->connections->connOpened == ctx->connections->poolSize)
+ if (ReleaseConnection(ctx, NULL, 0))
+ goto edg_wll_log_connect_end;
+ index = AddConnection(ctx, ctx->p_destination, ctx->p_dest_port);
+ if (index < 0) {
+ edg_wll_SetError(ctx,EAGAIN,"connection pool size exceeded");
+ goto edg_wll_log_connect_end;
+ }
+#if 0
+ /* acquire gss credentials */
+ ret = edg_wll_gss_acquire_cred_gsi(
+ ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_cert_filename,
+ ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_key_filename,
+ &ctx->connections->connPool[index].gsiCred, &my_subject_name, &gss_stat);
+ /* give up if unable to acquire prescribed credentials, otherwise go on anonymously */
+ if (ret && ctx->p_proxy_filename) {
+ edg_wll_SetErrorGss(ctx, "edg_wll_gss_acquire_cred_gsi(): failed to load GSI credentials", &gss_stat);
+ goto edg_wll_log_connect_err;
+ }
+ /* gss_connect */
+ if (ctx->connections->connPool[index].gss.context == GSS_C_NO_CONTEXT) {
+
+ /* acquire gss credentials */
+ ret = edg_wll_gss_acquire_cred_gsi(
+ ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_cert_filename,
+ ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_key_filename,
+ &ctx->connections->connPool[index].gsiCred, &my_subject_name, &gss_stat);
+ /* give up if unable to acquire prescribed credentials, otherwise go on anonymously */
+ if (ret && ctx->p_proxy_filename) {
+ edg_wll_SetErrorGss(ctx, "edg_wll_gss_acquire_cred_gsi(): failed to load GSI credentials", &gss_stat);
+ goto edg_wll_log_connect_err;
+ }
+ if ((answer = edg_wll_gss_connect(
+ ctx->connections->connPool[index].gsiCred,
+ ctx->connections->connPool[index].peerName,
+ ctx->connections->connPool[index].peerPort,
+ &ctx->p_tmp_timeout,
+ &ctx->connections->connPool[index].gss,
+ &gss_stat)) < 0) {
+ answer = handle_gss_failures(ctx,answer,&gss_stat,"edg_wll_gss_connect()");
+ goto edg_wll_log_connect_err;
+ }
+ goto edg_wll_log_connect_end;
+ } else goto edg_wll_log_connect_end;
+
+edg_wll_log_connect_err:
+ if (index >= 0) CloseConnection(ctx, &index);
+ index = -1;
+
+edg_wll_log_connect_end:
+ if (index >= 0) edg_wll_connectionTryLock(ctx, index);
+ if (my_subject_name) free(my_subject_name);
+
+ edg_wll_poolUnlock();
+
+ *conn = index;
+ return answer;
+}
+
+/**
+ *----------------------------------------------------------------------
+ * close connection to locallogger
+ *----------------------------------------------------------------------
+ */
+int edg_wll_log_close(edg_wll_Context ctx, int conn)
+{
+ int ret = 0;
+
+ if (conn == -1) return 0;
+ ret = CloseConnection(ctx,&conn);
+ edg_wll_connectionUnlock(ctx,conn);
+ return ret;
+}
+
+/**
+ *----------------------------------------------------------------------
+ * write/send to locallogger
+ *----------------------------------------------------------------------
+ */
+int edg_wll_log_write(edg_wll_Context ctx, int conn, edg_wll_LogLine logline)
+{
+ char header[EDG_WLL_LOG_SOCKET_HEADER_LENGTH+1];
+ int err;
+ int answer;
+ size_t count,sent;
+ int size;
+ u_int8_t size_end[4];
+ edg_wll_GssStatus gss_code;
+
+ errno = err = answer = count = sent = 0;
+ size = strlen(logline)+1;
+ size_end[0] = size & 0xff; size >>= 8;
+ size_end[1] = size & 0xff; size >>= 8;
+ size_end[2] = size & 0xff; size >>= 8;
+ size_end[3] = size;
+ size = strlen(logline)+1;
+
+ edg_wll_ResetError(ctx);
+
+ sprintf(header,"%s",EDG_WLL_LOG_SOCKET_HEADER);
+ header[EDG_WLL_LOG_SOCKET_HEADER_LENGTH]='\0';
+ if ((err = edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, header, EDG_WLL_LOG_SOCKET_HEADER_LENGTH, &ctx->p_tmp_timeout, &count, &gss_code)) < 0) {
+ switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_write_full()")) {
+ case ENOTCONN:
+ edg_wll_log_close(ctx,conn);
+ if (edg_wll_log_connect(ctx,&conn) ||
+ edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, header, EDG_WLL_LOG_SOCKET_HEADER_LENGTH, &ctx->p_tmp_timeout, &count, &gss_code) < 0) {
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending header");
+ return -1;
+ }
+ break;
+ case 0:
+ break;
+ default:
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending header");
+ return -1;
+ }
+ }
+ sent += count;
+
+ count = 0;
+ if ((err = edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, size_end, 4, &ctx->p_tmp_timeout, &count, &gss_code)) < 0) {
+ switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_write_full()")) {
+ case ENOTCONN:
+ edg_wll_log_close(ctx,conn);
+ if (edg_wll_log_connect(ctx,&conn) ||
+ edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, size_end, 4, &ctx->p_tmp_timeout, &count, &gss_code) < 0) {
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message size");
+ return -1;
+ }
+ break;
+ case 0:
+ break;
+ default:
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message size");
+ return -1;
+
+ }
+ }
+ sent += count;
+
+ count = 0;
+ if (( err = edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, logline, size, &ctx->p_tmp_timeout, &count, &gss_code)) < 0) {
+ switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_write_full()")) {
+ case ENOTCONN:
+ edg_wll_log_close(ctx,conn);
+ if (edg_wll_log_connect(ctx,&conn) ||
+ edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, logline, size, &ctx->p_tmp_timeout, &count, &gss_code) < 0) {
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message");
+ return -1;
+ }
+ break;
+ case 0:
+ break;
+ default:
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message");
+ return -1;
+ }
+ }
+ sent += count;
+
+ return sent;
+}
+
+/**
+ *----------------------------------------------------------------------
+ * read/receive from locallogger
+ *----------------------------------------------------------------------
+ */
+int edg_wll_log_read(edg_wll_Context ctx, int conn)
+{
+ int err;
+ int answer;
+ u_int8_t answer_end[4];
+ size_t count;
+ edg_wll_GssStatus gss_code;
+
+ errno = err = answer = count = 0;
+
+ edg_wll_ResetError(ctx);
+
+ count = 0;
+ if ((err = edg_wll_gss_read_full(&ctx->connections->connPool[conn].gss, answer_end, 4, &ctx->p_tmp_timeout, &count, &gss_code)) < 0 ) {
+ switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_read_full()")) {
+ case ENOTCONN:
+ edg_wll_log_close(ctx,conn);
+ if (edg_wll_log_connect(ctx,&conn) ||
+ edg_wll_gss_read_full(&ctx->connections->connPool[conn].gss, answer_end, 4, &ctx->p_tmp_timeout, &count, &gss_code) < 0 ) {
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_read(): error reading answer from local-logger");
+ return -1;
+ }
+ break;
+ case 0:
+ break;
+ default:
+ edg_wll_UpdateError(ctx,answer,"edg_wll_log_read(): error reading answer from local-logger");
+ return -1;
+ }
+ }
+ answer = answer_end[3]; answer <<=8;
+ answer |= answer_end[2]; answer <<=8;
+ answer |= answer_end[1]; answer <<=8;
+ answer |= answer_end[0];
+ edg_wll_SetError(ctx,answer,"edg_wll_log_read(): answer read from locallogger");
+
+ return count;
+}
--- /dev/null
+#include <jni.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <pwd.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define tv_sub(a, b) {\
+ (a).tv_usec -= (b).tv_usec;\
+ (a).tv_sec -= (b).tv_sec;\
+ if ((a).tv_usec < 0) {\
+ (a).tv_sec--;\
+ (a).tv_usec += 1000000;\
+ }\
+}
+
+
+/*!
+ * Write to socket
+ * Needn't write entire buffer. Timeout is applicable only for non-blocking
+ * connections
+ * \param sock IN: connection to work with
+ * \param buf IN: buffer
+ * \param bufsize IN: max size to write
+ * \param timeout INOUT: max time allowed for operation, remaining time on return
+ * \retval bytes written (>0) on success
+ * \retval -1 on write error
+ */
+static ssize_t
+edg_wll_socket_write(
+ int sock,
+ const void *buf,
+ size_t bufsize,
+ struct timeval *timeout)
+{
+ ssize_t len = 0;
+ fd_set fds;
+ struct timeval to, before, after;
+
+
+ if ( timeout ) {
+ memcpy(&to, timeout, sizeof to);
+ gettimeofday(&before, NULL);
+ }
+ len = write(sock, buf, bufsize);
+ if ( len <= 0 && errno == EAGAIN ) {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ if ( select(sock+1, NULL, &fds, NULL, timeout? &to: NULL) < 0 ) {
+ len = -1;
+ } else {
+ len = write(sock, buf, bufsize);
+ }
+ }
+ if ( timeout ) {
+ gettimeofday(&after, NULL);
+ tv_sub(after, before);
+ tv_sub(*timeout, after);
+ if ( timeout->tv_sec < 0 ) {
+ timeout->tv_sec = 0;
+ timeout->tv_usec = 0;
+ }
+ }
+
+ return len;
+}
+
+/*!
+ * Write specified amount of data to socket
+ * Attempts to call edg_wll_socket_write() untill the entire request is satisfied
+ * (or times out).
+ * \param sock IN: connection to work with
+ * \param buf IN: buffer
+ * \param bufsize IN: max size to write
+ * \param timeout INOUT: max time allowed for operation, remaining time on return
+ * \param total OUT: bytes actually written
+ * \retval bytes written (>0) on success
+ * \retval -1 on write error
+ */
+static ssize_t
+edg_wll_socket_write_full(
+ int sock,
+ void *buf,
+ size_t bufsize,
+ struct timeval *timeout,
+ ssize_t *total)
+{
+ ssize_t len;
+ *total = 0;
+
+ while ( *total < bufsize ) {
+ len = edg_wll_socket_write(sock, buf+*total, bufsize-*total, timeout);
+ if (len < 0) return len;
+ *total += len;
+ }
+
+ return 0;
+}
+
+/*
+ * edg_wll_log_event_send - send event to the socket
+ *
+ * Returns: 0 if done properly or errno
+ *
+ */
+/*int edg_wll_log_event_send(
+ const char *socket_path,
+ long filepos,
+ const char *msg,
+ int msg_size,
+ int conn_attempts,
+ int timeout_int)*/
+/*JNIEXPORT jint JNICALL Java_org_glite_lb_ContextIL_edg_wll_log_event_send
+ (JNIEnv *env,
+ jobject jobj,
+ jstring socket_path_j,
+ jlong filepos_j,
+ jstring msg_j,
+ jint msg_size_j,
+ jint conn_attempts_j,
+ jint timeout_int_j)*/
+JNIEXPORT jint JNICALL Java_org_glite_lb_client_1java_ContextIL_sendToSocket
+ (JNIEnv *env,
+ jobject jobj,
+ jstring socket_path_j,
+ jlong filepos_j,
+ jstring msg_j,
+ jint msg_size_j,
+ jint conn_attempts_j,
+ jint timeout_int_j)
+
+{
+ const char *socket_path = (*env)->GetStringUTFChars(env, socket_path_j, 0);
+ const char *msg = (*env)->GetStringUTFChars(env, msg_j, 0);
+ int timeout_int = (int) timeout_int_j;
+ //int timeout_int = 3;
+ long filepos = (long) filepos_j;
+ int msg_size = (int) msg_size_j;
+ int conn_attempts = (int) conn_attempts_j;
+ //int conn_attempts = 3;
+ struct timeval timeout;
+ timeout.tv_sec = timeout_int;
+ timeout.tv_usec = 0;
+ struct sockaddr_un saddr;
+ int msg_sock,
+ flags,
+ conn_timeout, i;
+ ssize_t count = 0;
+
+
+ if ( (msg_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
+ goto event_send_end;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sun_family = AF_UNIX;
+ strcpy(saddr.sun_path, socket_path);
+
+ if ( (flags = fcntl(msg_sock, F_GETFL, 0)) < 0
+ || fcntl(msg_sock, F_SETFL, flags | O_NONBLOCK) < 0 ) {
+ goto cleanup;
+ }
+
+ conn_timeout = floor(timeout.tv_sec/(conn_attempts + 1));
+ for ( i = 0; i < conn_attempts; i++) {
+ if ( connect(msg_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0 ) {
+ if ( errno == EISCONN ) break;
+ else if ((errno == EAGAIN) || (errno == ETIMEDOUT)) {
+ sleep(conn_timeout);
+ timeout.tv_sec -= conn_timeout;
+ continue;
+ } else {
+ goto cleanup;
+ }
+ } else break;
+ }
+
+ if ( edg_wll_socket_write_full(msg_sock, &filepos, sizeof(filepos), &timeout, &count) < 0
+) {
+ goto cleanup;
+ }
+
+ if ( edg_wll_socket_write_full(msg_sock, (void *)msg, msg_size,
+&timeout, &count) < 0 ) {
+ goto cleanup;
+ }
+
+cleanup:
+ close(msg_sock);
+
+event_send_end:
+ return 0;
+}