Imported Upstream version 1.5.1

This commit is contained in:
Mario Fetka
2020-09-22 02:25:22 +02:00
commit 434d6067d9
2103 changed files with 928962 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
<?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.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="Flease" default="default" basedir=".">
<description>Builds, tests, and runs the project Flease.</description>
<import file="nbproject/build-impl-1.6.5.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="Flease-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>

75
java/flease/build.xml Normal file
View File

@@ -0,0 +1,75 @@
<?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.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="Flease" default="default" basedir=".">
<description>Builds, tests, and runs the project Flease.</description>
<import file="nbproject/build-impl.xml"/>
<import file="nbproject/profiler-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="Flease-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>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry combineaccessrules="false" kind="src" path="/xtreemfs_foundation"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="../lib/test/junit-4.11.jar"/>
<classpathentry kind="lib" path="../lib/test/hamcrest-core-1.3.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>xtreemfs_flease</name>
<comment></comment>
<projects>
<project>xtreemfs_foundation</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

3
java/flease/manifest.mf Normal file
View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

View File

@@ -0,0 +1,892 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- compilation
- jar
- execution
- debugging
- javadoc
- junit compilation
- junit execution
- junit debugging
- applet
- cleanup
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Flease-impl">
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
<target depends="-pre-init,-init-private" name="-init-user">
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
<available file="${application.splash}" property="splashscreen.available"/>
<condition property="main.class.available">
<and>
<isset property="main.class"/>
<not>
<equals arg1="${main.class}" arg2="" trim="true"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class">
<and>
<isset property="manifest.available"/>
<isset property="main.class.available"/>
</and>
</condition>
<condition property="do.mkdist">
<and>
<isset property="libs.CopyLibs.classpath"/>
<not>
<istrue value="${mkdist.disabled}"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class}"/>
<isset property="do.mkdist"/>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available+splashscreen.available">
<and>
<istrue value="${manifest.available+main.class+mkdist.available}"/>
<istrue value="${splashscreen.available}"/>
</and>
</condition>
<condition property="do.archive">
<not>
<istrue value="${jar.archive.disabled}"/>
</not>
</condition>
<condition property="do.archive+manifest.available">
<and>
<isset property="manifest.available"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="do.archive+manifest.available+main.class">
<and>
<istrue value="${manifest.available+main.class}"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="do.archive+manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class+mkdist.available}"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available">
<and>
<istrue value="${manifest.available+main.class+mkdist.available+splashscreen.available}"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="have.tests">
<or>
<available file="${test.src.dir}"/>
</or>
</condition>
<condition property="have.sources">
<or>
<available file="${src.dir}"/>
</or>
</condition>
<condition property="netbeans.home+have.tests">
<and>
<isset property="netbeans.home"/>
<isset property="have.tests"/>
</and>
</condition>
<condition property="no.javadoc.preview">
<and>
<isset property="javadoc.preview"/>
<isfalse value="${javadoc.preview}"/>
</and>
</condition>
<property name="run.jvmargs" value=""/>
<property name="javac.compilerargs" value=""/>
<property name="work.dir" value="${basedir}"/>
<condition property="no.deps">
<and>
<istrue value="${no.dependencies}"/>
</and>
</condition>
<property name="javac.debug" value="true"/>
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<property name="runtime.encoding" value="${source.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
<not>
<equals arg1="${javadoc.encoding}" arg2=""/>
</not>
</and>
</condition>
<property name="javadoc.encoding.used" value="${source.encoding}"/>
<property name="includes" value="**"/>
<property name="excludes" value=""/>
<property name="do.depend" value="false"/>
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
<path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
<condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
<length length="0" string="${endorsed.classpath}" when="greater"/>
</condition>
<property name="javac.fork" value="false"/>
<property name="jar.index" value="false"/>
<available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
</target>
<target name="-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
<fail unless="src.dir">Must set src.dir</fail>
<fail unless="test.src.dir">Must set test.src.dir</fail>
<fail unless="build.dir">Must set build.dir</fail>
<fail unless="dist.dir">Must set dist.dir</fail>
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
<fail unless="dist.jar">Must set dist.jar</fail>
</target>
<target name="-init-macrodef-property">
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
</target>
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${javac.processorpath}" name="processorpath"/>
<attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="${empty.dir}" name="sourcepath"/>
<attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
<property location="${build.dir}/empty" name="empty.dir"/>
<mkdir dir="${empty.dir}"/>
<mkdir dir="@{gensrcdir}"/>
<mkdir dir="@{apgeneratedsrcdir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
<src>
<dirset dir="@{gensrcdir}">
<include name="*"/>
</dirset>
</src>
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
<compilerarg line="${javac.compilerargs}"/>
<compilerarg value="-processorpath"/>
<compilerarg path="@{processorpath}:${empty.dir}"/>
<compilerarg line="${ap.processors.internal}"/>
<compilerarg line="${annotation.processing.processor.options}"/>
<compilerarg value="-s"/>
<compilerarg path="@{apgeneratedsrcdir}"/>
<compilerarg line="${ap.proc.none.internal}"/>
<customize/>
</javac>
</sequential>
</macrodef>
</target>
<target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${javac.processorpath}" name="processorpath"/>
<attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="${empty.dir}" name="sourcepath"/>
<attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
<property location="${build.dir}/empty" name="empty.dir"/>
<mkdir dir="${empty.dir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
<src>
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</src>
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
<compilerarg line="${javac.compilerargs}"/>
<customize/>
</javac>
</sequential>
</macrodef>
</target>
<target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<sequential>
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</depend>
</sequential>
</macrodef>
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
<pathconvert pathsep="${line.separator}" property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
<tempfile deleteonexit="true" property="javac.includesfile.binary"/>
<echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
<delete>
<files includesfile="${javac.includesfile.binary}"/>
</delete>
<delete file="${javac.includesfile.binary}"/>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-junit">
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="**" name="testincludes"/>
<sequential>
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
<batchtest todir="${build.test.results.dir}">
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
<filename name="@{testincludes}"/>
</fileset>
</batchtest>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${run.jvmargs}"/>
</junit>
</sequential>
</macrodef>
</target>
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="name"/>
<attribute default="${debug.classpath}" name="classpath"/>
<attribute default="" name="stopclassname"/>
<sequential>
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</nbjpdastart>
</sequential>
</macrodef>
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${build.classes.dir}" name="dir"/>
<sequential>
<nbjpdareload>
<fileset dir="@{dir}" includes="${fix.classes}">
<include name="${fix.includes}*.class"/>
</fileset>
</nbjpdareload>
</sequential>
</macrodef>
</target>
<target name="-init-debug-args">
<property name="version-output" value="java version &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;1.3"/>
</or>
</condition>
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
<istrue value="${have-jdk-older-than-1.4}"/>
</condition>
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
<os family="windows"/>
</condition>
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
<isset property="debug.transport"/>
</condition>
</target>
<target depends="-init-debug-args" name="-init-macrodef-debug">
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${main.class}" name="classname"/>
<attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="classname"/>
<attribute default="${run.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-copylibs">
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
<element name="customize" optional="true"/>
<sequential>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Class-Path" value="${jar.classpath}"/>
<customize/>
</manifest>
</copylibs>
</sequential>
</macrodef>
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
<j2seproject1:fileset dir="${build.classes.dir}"/>
</jar>
</presetdef>
</target>
<target name="-init-ap-cmdline-properties">
<property name="annotation.processing.enabled" value="true"/>
<property name="annotation.processing.processors.list" value=""/>
<property name="annotation.processing.processor.options" value=""/>
<property name="annotation.processing.run.all.processors" value="true"/>
<property name="javac.processorpath" value="${javac.classpath}"/>
<property name="javac.test.processorpath" value="${javac.test.classpath}"/>
<condition property="ap.supported.internal" value="true">
<!-- 'matches' below does not work with ant 1.6.5. Therefore disabled in this file and set to always true. -->
<istrue value="true"/>
<!--
<not>
<matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
</not>
-->
</condition>
</target>
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
<condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
<isfalse value="${annotation.processing.run.all.processors}"/>
</condition>
<condition else="" property="ap.proc.none.internal" value="-proc:none">
<isfalse value="${annotation.processing.enabled}"/>
</condition>
</target>
<target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
<property name="ap.cmd.line.internal" value=""/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
<!--
===================
COMPILATION SECTION
===================
-->
<target name="-deps-jar-init" unless="built-jar.properties">
<property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
<delete file="${built-jar.properties}" quiet="true"/>
</target>
<target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
<echo level="warn" message="Cycle detected: Flease was already built"/>
</target>
<target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
<mkdir dir="${build.dir}"/>
<touch file="${built-jar.properties}" verbose="false"/>
<property file="${built-jar.properties}" prefix="already.built.jar."/>
<antcall target="-warn-already-built-jar"/>
<propertyfile file="${built-jar.properties}">
<entry key="${basedir}" value=""/>
</propertyfile>
</target>
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
<target depends="init" name="-check-automatic-build">
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
</target>
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
<antcall target="clean"/>
</target>
<target depends="init,deps-jar" name="-pre-pre-compile">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="-pre-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-depend">
<pathconvert property="build.generated.subdirs">
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</pathconvert>
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target if="has.persistence.xml" name="-copy-persistence-xml">
<mkdir dir="${build.classes.dir}/META-INF"/>
<copy todir="${build.classes.dir}/META-INF">
<fileset dir="${meta.inf.dir}" includes="persistence.xml"/>
</copy>
</target>
<target name="-post-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
<target name="-pre-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile/>
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
<!--
====================
JAR BUILDING SECTION
====================
-->
<target depends="init" name="-pre-pre-jar">
<dirname file="${dist.jar}" property="dist.jar.dir"/>
<mkdir dir="${dist.jar.dir}"/>
</target>
<target name="-pre-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-without-manifest" unless="manifest.available">
<j2seproject1:jar/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
<j2seproject1:jar manifest="${manifest.file}">
<j2seproject1:manifest>
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
</j2seproject1:manifest>
</j2seproject1:jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available" name="-do-jar-with-libraries-and-splashscreen">
<basename file="${application.splash}" property="splashscreen.basename"/>
<mkdir dir="${build.classes.dir}/META-INF"/>
<copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
<j2seproject3:copylibs>
<customize>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
</customize>
</j2seproject3:copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries" unless="splashscreen.available">
<j2seproject3:copylibs>
<customize>
<attribute name="Main-Class" value="${main.class}"/>
</customize>
</j2seproject3:copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries-and-splashscreen,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
=================
-->
<target depends="init,compile" description="Run a main class." name="run">
<j2seproject1:java>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject1:java>
</target>
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
<target depends="init,compile-single" name="run-single">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
<target depends="init,compile-test-single" name="run-test-with-main">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
</target>
<!--
=================
DEBUGGING SECTION
=================
-->
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
</target>
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
</target>
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
</target>
<target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
</target>
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
<j2seproject1:nbjpdareload/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
<!--
===============
JAVADOC SECTION
===============
-->
<target depends="init" if="have.sources" name="-javadoc-build">
<mkdir dir="${dist.javadoc.dir}"/>
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
<classpath>
<path path="${javac.classpath}"/>
</classpath>
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="**/*.java"/>
</fileset>
</javadoc>
<copy todir="${dist.javadoc.dir}">
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/doc-files/**"/>
</fileset>
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="**/doc-files/**"/>
</fileset>
</copy>
</target>
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
</target>
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
<!--
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
<mkdir dir="${build.test.classes.dir}"/>
</target>
<target name="-pre-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-test-depend">
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
<target name="-pre-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
<!--
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target depends="init" if="have.tests" name="-pre-test-run">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
<target depends="init" if="have.tests" name="-pre-test-run-single">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
<delete file="${test.report.file}"/>
<mkdir dir="${build.test.results.dir}"/>
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
<customize>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<arg value="${test.class}"/>
<arg value="showoutput=true"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
</target>
<target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
<!--
=========================
APPLET EXECUTION SECTION
=========================
-->
<target depends="init,compile-single" name="run-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject1:java classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject1:java>
</target>
<!--
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject3:debug classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
<!--
===============
CLEANUP SECTION
===============
-->
<target name="-deps-clean-init" unless="built-clean.properties">
<property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
<delete file="${built-clean.properties}" quiet="true"/>
</target>
<target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
<echo level="warn" message="Cycle detected: Flease was already built"/>
</target>
<target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
<mkdir dir="${build.dir}"/>
<touch file="${built-clean.properties}" verbose="false"/>
<property file="${built-clean.properties}" prefix="already.built.clean."/>
<antcall target="-warn-already-built-clean"/>
<propertyfile file="${built-clean.properties}">
<entry key="${basedir}" value=""/>
</propertyfile>
</target>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
</target>
<target name="-post-clean">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
<target name="-check-call-dep">
<property file="${call.built.properties}" prefix="already.built."/>
<condition property="should.call.dep">
<not>
<isset property="already.built.${call.subproject}"/>
</not>
</condition>
</target>
<target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
<ant antfile="${call.script}" inheritall="false" target="${call.target}">
<propertyset>
<propertyref prefix="transfer."/>
<mapper from="transfer.*" to="*" type="glob"/>
</propertyset>
</ant>
</target>
</project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
build.xml.data.CRC32=3d699ec7
build.xml.script.CRC32=d8a5a904
build.xml.stylesheet.CRC32=958a1d3e@1.26.2.45
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=d06e30bd
nbproject/build-impl.xml.script.CRC32=318c6c3f
nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45
nbproject/profiler-build-impl.xml.data.CRC32=3d699ec7
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf@1.6.1

View File

@@ -0,0 +1,6 @@
compile.on.save=true
do.depend=false
do.jar=true
javac.debug=true
javadoc.preview=true
user.properties.file=/home/kleineweber/.netbeans/7.0/build.properties

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<data xmlns="http://www.netbeans.org/ns/profiler/1" version="0.9.1"/>
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
</project-private>

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="2_profiler.settings.code.region.cpu.res.buf.size">1000</entry>
<entry key="2_profiler.settings.sort.results.by.thread.cpu.time">false</entry>
<entry key="0_profiler.settings.instrumentation.filter.selectedprofiler.filter.type">profiler.simple.filter</entry>
<entry key="0_profiler.settings.instrument.empty.methods">false</entry>
<entry key="3_profiler.settings.override.jvm.args"/>
<entry key="0_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.name"/>
<entry key="1_profiler.settings.profiling.type">8</entry>
<entry key="0_profiler.settings.cpu.exclude.wait.time">true</entry>
<entry key="0_profiler.settings.override.working.dir"/>
<entry key="3_profiler.settings.instrument.empty.methods">false</entry>
<entry key="1_profiler.settings.thread.cpu.timer.on">false</entry>
<entry key="1_profiler.settings.instrumentation.root.methods.size">0</entry>
<entry key="3_profiler.settings.obj.alloc.stack.sampling.depth">0</entry>
<entry key="2_profiler.settings.override">false</entry>
<entry key="profiler.settings.lastselected">2</entry>
<entry key="2_profiler.settings.instrument.spawned.threads">true</entry>
<entry key="0_profiler.settings.threads.monitoring.enabled">false</entry>
<entry key="0_profiler.settings.istrument.getter.setter.methods">false</entry>
<entry key="3_profiler.settings.cpu.quick.filterprofiler.simple.filter.value"/>
<entry key="2_profiler.settings.instrumentation.filter.selectedprofiler.filter.type">profiler.simple.filter</entry>
<entry key="3_profiler.settings.cpu.quick.filterprofiler.simple.filter.type">1</entry>
<entry key="2_profiler.settings.n.profiled.threads.limit">32</entry>
<entry key="3_profiler.settings.instr.scheme">1</entry>
<entry key="1_profiler.settings.sort.results.by.thread.cpu.time">false</entry>
<entry key="2_profiler.settings.instr.scheme">3</entry>
<entry key="1_profiler.settings.instrument.method.invoke">true</entry>
<entry key="3_profiler.settings.profilingpoints.enabled">true</entry>
<entry key="1_profiler.settings.instr.scheme">3</entry>
<entry key="2_profiler.settings.sampling.interval">10</entry>
<entry key="0_profiler.settings.instr.scheme">1</entry>
<entry key="1_profiler.settings.run.gc.on.get.results.in.memory.profiling">true</entry>
<entry key="2_profiler.settings.settings.name">New CPU Analysis</entry>
<entry key="0_profiler.settings.sort.results.by.thread.cpu.time">false</entry>
<entry key="0_profiler.settings.profiling.type">1</entry>
<entry key="1_profiler.settings.cpu.exclude.wait.time">true</entry>
<entry key="3_profiler.settings.cpu.quick.filterprofiler.simple.filter.name">Quick filter...</entry>
<entry key="2_profiler.settings.obj.alloc.stack.sampling.interval">10</entry>
<entry key="3_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.type">0</entry>
<entry key="3_profiler.settings.override">false</entry>
<entry key="1_profiler.settings.obj.alloc.stack.sampling.depth">0</entry>
<entry key="1_profiler.settings.cpu.quick.filterprofiler.filter.type">profiler.simple.filter</entry>
<entry key="1_profiler.settings.instrumentation.marker.methods.size">0</entry>
<entry key="2_profiler.settings.thread.cpu.timer.on">false</entry>
<entry key="0_profiler.settigns.ispreset">true</entry>
<entry key="0_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.value"/>
<entry key="3_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.name"/>
<entry key="2_profiler.settings.override.working.dir"/>
<entry key="0_profiler.settings.cpu.quick.filterprofiler.simple.filter.type">1</entry>
<entry key="2_profiler.settings.cpu.quick.filterprofiler.simple.filter.value"/>
<entry key="2_profiler.settings.override.jvm.args"/>
<entry key="0_profiler.settings.profile.underlying.framework">false</entry>
<entry key="2_profiler.settings.profile.underlying.framework">false</entry>
<entry key="3_profiler.settings.thread.cpu.timer.on">false</entry>
<entry key="2_profiler.settings.cpu.exclude.wait.time">true</entry>
<entry key="2_profiler.settings.threads.monitoring.enabled">false</entry>
<entry key="1_profiler.settings.instrument.spawned.threads">false</entry>
<entry key="1_profiler.settings.n.profiled.threads.limit">32</entry>
<entry key="0_profiler.settings.cpu.quick.filterprofiler.simple.filter.name">Quick filter...</entry>
<entry key="2_profiler.settings.instrumentation.root.methods.size">0</entry>
<entry key="2_profiler.settings.instrument.empty.methods">false</entry>
<entry key="2_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.type">0</entry>
<entry key="3_profiler.settings.cpu.profiling.type">0</entry>
<entry key="1_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.value"/>
<entry key="3_profiler.settings.cpu.quick.filterprofiler.filter.type">profiler.simple.filter</entry>
<entry key="1_profiler.settings.sampling.interval">10</entry>
<entry key="2_profiler.settings.cpu.profiling.type">0</entry>
<entry key="0_profiler.settings.run.gc.on.get.results.in.memory.profiling">true</entry>
<entry key="1_profiler.settigns.ispreset">true</entry>
<entry key="2_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.name">Profile all classes</entry>
<entry key="0_profiler.settings.instrument.method.invoke">true</entry>
<entry key="0_profiler.settings.obj.alloc.stack.sampling.interval">10</entry>
<entry key="3_profiler.settings.cpu.exclude.wait.time">true</entry>
<entry key="1_profiler.settings.cpu.quick.filterprofiler.simple.filter.value"/>
<entry key="1_profiler.settings.code.region.cpu.res.buf.size">1000</entry>
<entry key="3_profiler.settings.instrumentation.marker.methods.size">0</entry>
<entry key="3_profiler.settings.instrument.method.invoke">true</entry>
<entry key="3_profiler.settings.code.region.cpu.res.buf.size">1000</entry>
<entry key="0_profiler.settings.instrumentation.marker.methods.size">0</entry>
<entry key="1_profiler.settings.instrumentation.filter.selectedprofiler.filter.type">profiler.simple.filter</entry>
<entry key="0_profiler.settings.override">false</entry>
<entry key="3_profiler.settings.obj.alloc.stack.sampling.interval">10</entry>
<entry key="1_profiler.settings.settings.name">Analyze Performance</entry>
<entry key="2_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.value"/>
<entry key="1_profiler.settings.cpu.quick.filterprofiler.simple.filter.type">1</entry>
<entry key="1_profiler.settings.cpu.profiling.type">0</entry>
<entry key="1_profiler.settings.override.jvm.args"/>
<entry key="2_profiler.settings.obj.alloc.stack.sampling.depth">0</entry>
<entry key="1_profiler.settings.instrument.empty.methods">false</entry>
<entry key="0_profiler.settings.cpu.quick.filterprofiler.filter.type">profiler.simple.filter</entry>
<entry key="3_profiler.settings.run.gc.on.get.results.in.memory.profiling">true</entry>
<entry key="1_profiler.settings.cpu.quick.filterprofiler.simple.filter.name">Quick filter...</entry>
<entry key="3_profiler.settings.instrument.spawned.threads">false</entry>
<entry key="2_profiler.settigns.ispreset">false</entry>
<entry key="1_profiler.settings.threads.monitoring.enabled">false</entry>
<entry key="0_profiler.settings.instrumentation.root.methods.size">0</entry>
<entry key="3_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.value"/>
<entry key="1_profiler.settings.override.working.dir"/>
<entry key="3_profiler.settings.istrument.getter.setter.methods">false</entry>
<entry key="1_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.type">0</entry>
<entry key="0_profiler.settings.n.profiled.threads.limit">32</entry>
<entry key="0_profiler.settings.cpu.quick.filterprofiler.simple.filter.value"/>
<entry key="3_profiler.settings.instrumentation.root.methods.size">0</entry>
<entry key="3_profiler.settings.n.profiled.threads.limit">32</entry>
<entry key="0_profiler.settings.cpu.profiling.type">0</entry>
<entry key="3_profiler.settings.instrumentation.filter.selectedprofiler.filter.type">profiler.simple.filter</entry>
<entry key="3_profiler.settings.settings.name">Analyze Memory</entry>
<entry key="3_profiler.settings.profiling.type">2</entry>
<entry key="0_profiler.settings.instrument.spawned.threads">false</entry>
<entry key="1_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.name">Profile all classes</entry>
<entry key="2_profiler.settings.instrumentation.marker.methods.size">0</entry>
<entry key="0_profiler.settings.obj.alloc.stack.sampling.depth">0</entry>
<entry key="3_profiler.settings.sampling.interval">10</entry>
<entry key="2_profiler.settings.cpu.quick.filterprofiler.filter.type">profiler.simple.filter</entry>
<entry key="0_profiler.settings.profilingpoints.enabled">true</entry>
<entry key="2_profiler.settings.cpu.quick.filterprofiler.simple.filter.type">1</entry>
<entry key="3_profiler.settigns.ispreset">true</entry>
<entry key="1_profiler.settings.override">false</entry>
<entry key="1_profiler.settings.obj.alloc.stack.sampling.interval">10</entry>
<entry key="3_profiler.settings.override.working.dir"/>
<entry key="2_profiler.settings.istrument.getter.setter.methods">false</entry>
<entry key="0_profiler.settings.sampling.interval">10</entry>
<entry key="1_profiler.settings.profile.underlying.framework">false</entry>
<entry key="2_profiler.settings.instrument.method.invoke">true</entry>
<entry key="3_profiler.settings.profile.underlying.framework">false</entry>
<entry key="1_profiler.settings.profilingpoints.enabled">true</entry>
<entry key="1_profiler.settings.istrument.getter.setter.methods">false</entry>
<entry key="2_profiler.settings.cpu.quick.filterprofiler.simple.filter.name">Quick filter...</entry>
<entry key="0_profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.type">0</entry>
<entry key="3_profiler.settings.sort.results.by.thread.cpu.time">false</entry>
<entry key="0_profiler.settings.thread.cpu.timer.on">false</entry>
<entry key="0_profiler.settings.override.jvm.args"/>
<entry key="3_profiler.settings.threads.monitoring.enabled">false</entry>
<entry key="2_profiler.settings.profiling.type">8</entry>
<entry key="0_profiler.settings.settings.name">Monitor Application</entry>
<entry key="0_profiler.settings.code.region.cpu.res.buf.size">1000</entry>
<entry key="2_profiler.settings.profilingpoints.enabled">true</entry>
<entry key="2_profiler.settings.run.gc.on.get.results.in.memory.profiling">true</entry>
</properties>

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- profiling
- applet profiling
-->
<project name="-profiler-impl" default="profile" basedir="..">
<target name="default" depends="profile" description="Build and profile the project."/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="profile-init" depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check"/>
<target name="-profile-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-profile-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-profile-init-macrodef-profile">
<macrodef name="resolve">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${env.@{value}}"/>
</sequential>
</macrodef>
<macrodef name="profile">
<attribute name="classname" default="${main.class}"/>
<element name="customize" optional="true"/>
<sequential>
<property environment="env"/>
<resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
<java fork="true" classname="@{classname}" dir="${profiler.info.dir}" jvm="${profiler.info.jvm}">
<jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg line="${profiler.info.jvmargs}"/>
<env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
<arg line="${application.args}"/>
<classpath>
<path path="${run.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper type="glob" from="run-sys-prop.*" to="*"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-profile-init-check" depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile">
<fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
<fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
</target>
<!--
=================
PROFILING SECTION
=================
-->
<target name="profile" if="netbeans.home" depends="profile-init,compile" description="Profile a project in the IDE.">
<nbprofiledirect>
<classpath>
<path path="${run.classpath}"/>
</classpath>
</nbprofiledirect>
<profile/>
</target>
<target name="profile-single" if="netbeans.home" depends="profile-init,compile-single" description="Profile a selected class in the IDE.">
<fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
<nbprofiledirect>
<classpath>
<path path="${run.classpath}"/>
</classpath>
</nbprofiledirect>
<profile classname="${profile.class}"/>
</target>
<!--
=========================
APPLET PROFILING SECTION
=========================
-->
<target name="profile-applet" if="netbeans.home" depends="profile-init,compile-single">
<nbprofiledirect>
<classpath>
<path path="${run.classpath}"/>
</classpath>
</nbprofiledirect>
<profile classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</profile>
</target>
<!--
=========================
TESTS PROFILING SECTION
=========================
-->
<target name="profile-test-single" if="netbeans.home" depends="profile-init,compile-test-single">
<nbprofiledirect>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
</nbprofiledirect>
<junit showoutput="true" fork="true" dir="${profiler.info.dir}" jvm="${profiler.info.jvm}" failureproperty="tests.failed" errorproperty="tests.failed">
<env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
<jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg line="${profiler.info.jvmargs}"/>
<test name="${profile.class}"/>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper type="glob" from="test-sys-prop.*" to="*"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
</junit>
</target>
</project>

View File

@@ -0,0 +1,73 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.run.all.processors=true
application.title=Flease
application.vendor=bjko
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/Flease.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=false
javac.classpath=\
${reference.XtreemFS-foundation.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
javac.source=1.6
javac.target=1.6
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit_4.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
project.XtreemFS-foundation=../foundation
reference.XtreemFS-foundation.jar=${project.XtreemFS-foundation}/dist/Foundation.jar
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=-ea
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>Flease</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
<references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
<reference>
<foreign-project>XtreemFS-foundation</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
</references>
</configuration>
</project>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<protobuf-config xmlns="http://tabor.waw.pl/netbeans/protobuf/generator/jaxb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tabor.waw.pl/netbeans/protobuf/generator/jaxb ProtobufConfig.xsd"><generator on="false" type="cpp"/><generator on="false" type="java"/><generator on="false" type="python"/></protobuf-config>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="JavaApplication5_protobuf" default="default" basedir="." xmlns:s="http://tabor.waw.pl/netbeans/protobuf/generator/jaxb">
<target name="protobuf-environment">
<echo message="user.properties.file:${user.properties.file}"/>
<dirname property="user.properties.dir" file="${user.properties.file}"/>
<echo message="user.properties.dir:${user.properties.dir}"/>
<property file="${user.properties.dir}/config/Preferences/pl/waw/tabor/netbeans/protobuf/generator.properties"/>
<property name="protobuf.executable" value="protoc"/>
<property name="build.generated.sources.dir.protobuf.java" value="${build.generated.sources.dir}/protobuf-java"/>
<property name="build.generated.sources.dir.protobuf.cpp" value="${build.generated.sources.dir}/protobuf-cpp"/>
<property name="build.generated.sources.dir.protobuf.python" value="${build.generated.sources.dir}/protobuf-python"/>
</target>
<target name="protobuf-code-generation" depends="-do-init,-init-macrodef-javac,protobuf-environment">
<fileset dir="${src.dir}" id="proto.classpath">
<include name="**/*.proto"/>
</fileset>
<pathconvert property="protofiles" pathsep=" " refid="proto.classpath"/>
<echo message="${protobuf.executable} -I ${basedir} ${protofiles}"/>
<exec executable="${protobuf.executable}" searchpath="true">
<arg line="-I ${basedir}"/>
<arg line="${protofiles}"/>
</exec>
</target>
</project>

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
/**
* Object represents a lease.
* @author bjko
*/
public class Flease {
public static final Flease EMPTY_LEASE = new Flease(null,null, 0,FleaseMessage.IGNORE_MASTER_EPOCH);
private final ASCIIString leaseHolder;
private final long leaseTimeout_ms;
private final ASCIIString cellId;
private final long masterEpochNumber;
public Flease(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber) {
this.cellId = cellId;
this.leaseHolder = leaseHolder;
this.leaseTimeout_ms = leaseTimeout_ms;
this.masterEpochNumber = masterEpochNumber;
}
/**
* @return the leaseHolder
*/
public ASCIIString getLeaseHolder() {
return leaseHolder;
}
/**
* @return the leaseTimeout_ms
*/
public long getLeaseTimeout_ms() {
return leaseTimeout_ms;
}
public boolean isValid() {
return (TimeSync.getGlobalTime() < leaseTimeout_ms);
}
public boolean isEmptyLease() {
return leaseTimeout_ms == 0;
}
public boolean equals(Object other) {
try {
Flease o = (Flease) other;
boolean sameTo = o.leaseTimeout_ms == this.leaseTimeout_ms;
return isSameLeaseHolder(o) && sameTo;
} catch (ClassCastException ex) {
return false;
}
}
public boolean isSameLeaseHolder(Flease o) {
return (o.leaseHolder == this.leaseHolder) ||
(o.leaseHolder != null) && (this.leaseHolder != null) && (o.leaseHolder.equals(this.leaseHolder));
}
/**
* @return the cellId
*/
ASCIIString getCellId() {
return cellId;
}
public String toString() {
return (cellId == null ? "" : cellId.toString())+": "+
(leaseHolder == null ? "null" : leaseHolder.toString())+"/"+
leaseTimeout_ms;
}
/**
* @return the masterEpochNumber
*/
public long getMasterEpochNumber() {
return masterEpochNumber;
}
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import java.net.InetSocketAddress;
import org.xtreemfs.foundation.buffer.ASCIIString;
/**
*
* @author bjko
*/
public class FleaseConfig {
/**
* maximum lease timeout used in the system
*/
private final int maxLeaseTimeout_ms;
/**
* maximum clock drift allowed
*/
private final int dmax_ms;
/**
* used to discard old messages
*/
private final int messageTimeout_ms;
/**
* time the proposer waits for an answer
*/
private final int roundTimeout_ms;
private final int cellTimeout_ms;
private final int restartWait_ms;
private final int senderId;
private final InetSocketAddress endpoint;
private final ASCIIString identity;
private final int maxRetries;
private final boolean sendLearnMessages;
private final int toNotification_ms;
private final boolean debugPrintMessages;
public FleaseConfig(int leaseTimeout_ms, int dmax_ms,
int messageTimeout_ms, InetSocketAddress endpoint,
String identity, int maxRetries) {
this(leaseTimeout_ms,dmax_ms,messageTimeout_ms,endpoint,identity,maxRetries,true,0);
}
public FleaseConfig(int leaseTimeout_ms, int dmax_ms,
int messageTimeout_ms, InetSocketAddress endpoint,
String identity, int maxRetries, boolean sendLearnMessages,
int toNotification_ms) {
this(leaseTimeout_ms, dmax_ms, messageTimeout_ms, endpoint, identity, maxRetries, sendLearnMessages, toNotification_ms, false);
}
public FleaseConfig(int leaseTimeout_ms, int dmax_ms,
int messageTimeout_ms, InetSocketAddress endpoint,
String identity, int maxRetries, boolean sendLearnMessages,
int toNotification_ms, boolean debugPrintMessages) {
this.maxLeaseTimeout_ms = leaseTimeout_ms;
this.dmax_ms = dmax_ms;
this.messageTimeout_ms = messageTimeout_ms;
this.cellTimeout_ms = maxLeaseTimeout_ms*2;
this.roundTimeout_ms = messageTimeout_ms*2;
this.restartWait_ms = maxLeaseTimeout_ms+dmax_ms*2+messageTimeout_ms;
this.endpoint = endpoint;
this.senderId = identity.hashCode();
checkValidConfiguration();
this.identity = new ASCIIString(identity);
this.maxRetries = maxRetries;
this.sendLearnMessages = sendLearnMessages;
this.toNotification_ms = toNotification_ms;
this.debugPrintMessages = debugPrintMessages;
}
public void checkValidConfiguration() {
if (maxLeaseTimeout_ms < dmax_ms*2) {
throw new IllegalArgumentException("maxLeaseTimeout_ms must be at least twice as long as dmax_ms but should be much bigger");
}
if (maxLeaseTimeout_ms < dmax_ms*2+roundTimeout_ms*2) {
throw new IllegalArgumentException("maxLeaseTimeout_ms must be at least as long as dmax_ms*2+4*message_timeout but should be much bigger");
}
}
/**
* @return the leaseTimeout_ms
*/
public int getMaxLeaseTimeout() {
return maxLeaseTimeout_ms;
}
/**
* @return the dmax_ms
*/
public int getDMax() {
return dmax_ms;
}
/**
* @return the maxPxWait_ms
*/
public int getMessageTimeout() {
return messageTimeout_ms;
}
/**
* @return the cellTimeout_ms
*/
public int getCellTimeout() {
return cellTimeout_ms;
}
/**
* @return the restartWait_ms
*/
public int getRestartWait() {
return restartWait_ms;
}
/**
* @return the senderId
*/
public int getSenderId() {
return senderId;
}
/**
* @return the endpoint
*/
public InetSocketAddress getEndpoint() {
return endpoint;
}
public ASCIIString getIdentity() {
return identity;
}
public int getRoundTimeout() {
return roundTimeout_ms;
}
public int getMaxRetries() {
return maxRetries;
}
/**
* @return the sendLearnMessages
*/
public boolean isSendLearnMessages() {
return sendLearnMessages;
}
/**
* @return the toNotification_ms
*/
public int getToNotification_ms() {
return toNotification_ms;
}
/**
* @return the debugPrintMessages
*/
public boolean isDebugPrintMessages() {
return debugPrintMessages;
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
import org.xtreemfs.foundation.flease.proposer.FleaseListener;
/**
*
* @author bjko
*/
public class FleaseFuture implements FleaseListener {
private volatile Flease result;
private volatile FleaseException error;
FleaseFuture() {
result = null;
}
public Flease get() throws FleaseException,InterruptedException {
synchronized (this) {
if ((result == null) && (error == null))
this.wait();
if (error != null)
throw error;
return result;
}
}
public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber) {
synchronized (this) {
result = new Flease(cellId,leaseHolder,leaseTimeout_ms,masterEpochNumber);
this.notifyAll();
}
}
public void proposalFailed(ASCIIString cellId, Throwable cause) {
synchronized (this) {
if (cause instanceof FleaseException) {
error = (FleaseException) cause;
} else {
error = new FleaseException(cause.getMessage(), cause);
}
this.notifyAll();
}
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
/**
*
* @author bjko
*/
public interface FleaseMessageSenderInterface {
public void sendMessage(FleaseMessage message, InetSocketAddress recipient);
}

View File

@@ -0,0 +1,691 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.xtreemfs.foundation.LifeCycleThread;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptor;
import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptorCell;
import org.xtreemfs.foundation.flease.acceptor.LearnEventListener;
import org.xtreemfs.foundation.flease.comm.FleaseCommunicationInterface;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
import org.xtreemfs.foundation.flease.proposer.FleaseListener;
import org.xtreemfs.foundation.flease.proposer.FleaseLocalQueueInterface;
import org.xtreemfs.foundation.flease.proposer.FleaseProposer;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
*
* @author bjko
*/
public class FleaseStage extends LifeCycleThread implements LearnEventListener, FleaseLocalQueueInterface {
public static final String FLEASE_VERSION = "0.2.4 (trunk)";
public static final int TIMER_INTERVAL_IN_MS = 50;
public static final boolean ENABLE_TIMEOUT_EVENTS = true;
public static final boolean DISABLE_RENEW_FOR_TESTING = false;
public static final boolean COLLECT_STATISTICS = false;
private final FleaseProposer proposer;
private final FleaseAcceptor acceptor;
private final PriorityQueue<TimerEntry> timers;
private final PriorityQueue<Flease> leaseTimeouts;
private final LinkedBlockingQueue messages;
private volatile boolean quit;
private long lastTimerRun;
private final FleaseConfig config;
private final FleaseMessageSenderInterface sender;
public static final int MAX_BATCH_SIZE = 20;
private final FleaseStatusListener leaseListener;
private final AtomicReference<List<Integer>> durRequests, durMsgs, durTimers;
private final AtomicInteger inRequests, inMsgs, inTimers, outMsgs;
private final FleaseStats statThr;
private final MasterEpochHandlerInterface meHandler;
/**
* Creates a new instance of Flease.
* @param config flease configuration used for all cells and leases.
* @param lockfileDir a lockfile for this flease instance is created in this directory.
* @param sender interface to send flease messages to other flease nodes.
* @param ignoreLockForTesting should only be used by unit tests.
* @param viewListener not used at the moment, can be null.
* @param leaseListener listener is notified when the lease changes for any open cell.
* @param meHandler handler for storing/retrieving master epochs, can be null.
* @throws IOException
*/
public FleaseStage(FleaseConfig config, String lockfileDir,
final FleaseMessageSenderInterface sender, boolean ignoreLockForTesting,
final FleaseViewChangeListenerInterface viewListener, final FleaseStatusListener leaseListener,
final MasterEpochHandlerInterface meHandler) throws IOException {
super("FleaseSt");
assert (sender != null);
assert(leaseListener != null);
timers = new PriorityQueue<TimerEntry>();
messages = new LinkedBlockingQueue();
quit = false;
this.config = config;
this.leaseListener = leaseListener;
this.meHandler = meHandler;
acceptor = new FleaseAcceptor(this, config, lockfileDir, ignoreLockForTesting);
proposer = new FleaseProposer(config, acceptor, new FleaseCommunicationInterface() {
public void sendMessage(FleaseMessage msg, InetSocketAddress receiver) throws IOException {
sender.sendMessage(msg, receiver);
}
public void requestTimer(FleaseMessage msg, long timestamp) {
createTimer(msg, timestamp);
}
}, leaseListener, this, this,meHandler);
acceptor.setViewChangeListener(viewListener);
proposer.setViewChangeListener(viewListener);
this.sender = sender;
leaseTimeouts = new PriorityQueue<Flease>(1000, new Comparator<Flease>() {
public int compare(Flease o1, Flease o2) {
return (int) (o1.getLeaseTimeout_ms() - o2.getLeaseTimeout_ms());
}
});
if (COLLECT_STATISTICS) {
durRequests = new AtomicReference(new LinkedList());
durTimers = new AtomicReference(new LinkedList());
durMsgs = new AtomicReference(new LinkedList());
inRequests = new AtomicInteger();
inTimers = new AtomicInteger();
inMsgs = new AtomicInteger();
outMsgs = new AtomicInteger();
statThr = new FleaseStats(this, lockfileDir+"/flease.stats");
} else {
durRequests = null;
durTimers = null;
durMsgs = null;
outMsgs = null;
inRequests = null;
inTimers = null;
inMsgs = null;
statThr = null;
}
}
public ASCIIString getIdentity() {
return config.getIdentity();
}
@Deprecated
public FleaseFuture openCell(ASCIIString cellId, List<InetSocketAddress> acceptors, boolean requestMasterEpoch) {
return openCell(cellId, acceptors, requestMasterEpoch, 0);
}
/**
* Opens a cell. The leaseListener will be notified of all lease events for this cell. The local flease
* instance will try to acquire the lease.
*
* @param cellId
* unique ID of the cell to open.
* @param acceptors
* list of remote flease instances, do not include local flease instance.
* @param requestMasterEpoch
* if true, a master epoch will be requested when the local instance is lease owner.
* @param viewId
* the current view id to open the cell with.
* @return
*/
public FleaseFuture openCell(ASCIIString cellId, List<InetSocketAddress> acceptors, boolean requestMasterEpoch,
int viewId) {
FleaseFuture f = new FleaseFuture();
Request rq = new Request(Request.RequestType.OPEN_CELL_REQUEST);
rq.cellId = cellId;
rq.acceptors = acceptors;
rq.listener = f;
rq.requestME = requestMasterEpoch;
rq.viewId = viewId;
if (COLLECT_STATISTICS)
inRequests.incrementAndGet();
this.messages.add(rq);
return f;
}
public void batchOpenCells(ASCIIString[] cellIds, List<InetSocketAddress>[] acceptors, boolean requestMasterEpoch) {
List<Request> batch = new ArrayList(cellIds.length);
for (int i =0; i < cellIds.length; i++) {
Request rq = new Request(Request.RequestType.OPEN_CELL_REQUEST);
rq.cellId = cellIds[i];
rq.acceptors = acceptors[i];
rq.listener = null;
rq.requestME = requestMasterEpoch;
batch.add(rq);
}
for (int i = 0; i < batch.size(); i += MAX_BATCH_SIZE) {
int endIndex = i+MAX_BATCH_SIZE;
if (endIndex > batch.size()-1)
endIndex = batch.size();
List<Request> sublist = batch.subList(i, endIndex);
if (COLLECT_STATISTICS)
inRequests.addAndGet(sublist.size());
this.messages.addAll(sublist);
}
}
/**
* Closes a cell which must be open. If the local instance is the current lease owner,
* the lease will not be renewed.
* @param cellId
* @param returnLease if true, the lease will immediately be released.
* @return
*/
public FleaseFuture closeCell(ASCIIString cellId, boolean returnLease) {
// TODO(bjko): return lease, check if not_owner event is triggered.
FleaseFuture f = new FleaseFuture();
Request rq = new Request(Request.RequestType.CLOSE_CELL_REQUEST);
rq.cellId = cellId;
rq.listener = f;
if (COLLECT_STATISTICS)
inRequests.incrementAndGet();
this.messages.add(rq);
return f;
}
public void setViewId(ASCIIString cellId, int viewId, FleaseListener listener) {
Request rq = new Request(Request.RequestType.SET_VIEW);
rq.cellId = cellId;
rq.viewId = viewId;
rq.listener = listener;
if (COLLECT_STATISTICS)
inRequests.incrementAndGet();
this.messages.add(rq);
}
public Map<ASCIIString, FleaseMessage> getLocalState() throws InterruptedException {
final Request rq = new Request(Request.RequestType.GET_STATE);
final Map[] map = new Map[1];
rq.cback = new FleaseStateCallback() {
public void localStateResult(Map<ASCIIString, FleaseMessage> state) {
synchronized (rq) {
map[0] = state;
rq.notifyAll();
}
}
};
this.messages.add(rq);
synchronized (rq) {
if (map[0] == null) {
rq.wait();
}
return map[0];
}
}
public void receiveMessage(FleaseMessage msg) {
assert (msg.getSender() != null);
if (COLLECT_STATISTICS)
inMsgs.incrementAndGet();
this.messages.add(msg);
}
public FleaseMessage _test_get_local_lease_state(ASCIIString cellId) {
return acceptor.getLocalLeaseInformation(cellId);
}
public String _dump_acceptor_state(ASCIIString cellId) {
FleaseAcceptorCell cell = acceptor.cells.get(cellId);
if (cell == null) {
return cellId + ": does not exist";
} else {
return cellId + ": " + cell.toString();
}
}
public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"learned event: "+leaseHolder+"/"+leaseTimeout_ms);
}
Flease newFlease = new Flease(cellId, leaseHolder, leaseTimeout_ms, masterEpochNumber);
Flease oldFlease = proposer.updatePrevLeaseForCell(cellId, newFlease);
if (oldFlease != null) {
if (oldFlease.isValid()) {
if (!oldFlease.isSameLeaseHolder(newFlease)) {
Logging.logMessage(
Logging.LEVEL_DEBUG,
Category.replication,
this,
"New lease replaced old lease which is still valid according to this OSD's clocks. Make sure all OSD clocks are synchronized. New Lease: %s Old Lease: %s",
newFlease, oldFlease);
}
}
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"lease state change: %s %s %d",cellId,leaseHolder,leaseTimeout_ms);
}
leaseListener.statusChanged(cellId, newFlease);
if (ENABLE_TIMEOUT_EVENTS) {
leaseTimeouts.remove(oldFlease);
leaseTimeouts.add(newFlease);
}
}
}
@Override
public void run() {
if (COLLECT_STATISTICS)
statThr.start();
Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this, "Flease (version %s) ready", FLEASE_VERSION);
notifyStarted();
// interval to check the OFT
long nextTimerRunInMS = TIMER_INTERVAL_IN_MS;
lastTimerRun = 0;
List<Object> rqList = new ArrayList(1000);
while (!quit) {
try {
final Object tmp = messages.poll(nextTimerRunInMS, TimeUnit.MILLISECONDS);
if (quit) {
break;
}
if ((tmp == null) ||
(TimeSync.getLocalSystemTime() >= lastTimerRun + nextTimerRunInMS)) {
if (ENABLE_TIMEOUT_EVENTS) {
//nextTimerRunInMS =
checkTimers();
checkLeaseTimeouts();
} else {
nextTimerRunInMS = checkTimers();
}
lastTimerRun = TimeSync.getLocalSystemTime();
}
if (tmp == null) {
continue;
}
rqList.add(tmp);
messages.drainTo(rqList, 25);
/*final int numItems = messages.poll(rqList, 25, nextTimerRunInMS);
if ((numItems == 0) ||
(TimeSync.getLocalSystemTime() >= lastTimerRun+nextTimerRunInMS)) {
nextTimerRunInMS = checkTimers();
lastTimerRun = TimeSync.getLocalSystemTime();
}
if (numItems == 0)
continue;*/
while (!rqList.isEmpty()) {
final Object request = rqList.remove(rqList.size() - 1);
long rqStart;
if (COLLECT_STATISTICS) {
rqStart = System.nanoTime();
}
if (request instanceof FleaseMessage) {
final FleaseMessage msg = (FleaseMessage) request;
if (msg.isInternalEvent()) {
//should never happen!
Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, "received internal event: %s", msg);
} else if (msg.isAcceptorMessage()) {
final FleaseMessage response = acceptor.processMessage(msg);
if (response != null) {
if (msg.getMasterEpochNumber() == FleaseMessage.REQUEST_MASTER_EPOCH
&& response.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE_ACK) {
// Respond with the current master epoch.
if (meHandler != null) {
MasterEpochHandlerInterface.Continuation cont = new MasterEpochHandlerInterface.Continuation() {
@Override
public void processingFinished() {
sender.sendMessage(response, msg.getSender());
}
};
meHandler.sendMasterEpoch(response, cont);
} else {
Logging.logMessage(Logging.LEVEL_ERROR, this,
"MASTER EPOCH WAS REQUESTED, BUT NO MASTER EPOCH HANDLER DEFINED!!!");
sender.sendMessage(response, msg.getSender());
}
} else if (msg.getMasterEpochNumber() != FleaseMessage.IGNORE_MASTER_EPOCH
&& response.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT_ACK) {
// Write the current master epoch to disk.
if (meHandler != null) {
MasterEpochHandlerInterface.Continuation cont = new MasterEpochHandlerInterface.Continuation() {
@Override
public void processingFinished() {
sender.sendMessage(response, msg.getSender());
}
};
meHandler.storeMasterEpoch(response, cont);
}
} else {
sender.sendMessage(response, msg.getSender());
}
}
} else {
proposer.processMessage(msg);
}
if (COLLECT_STATISTICS) {
long rqEnd = System.nanoTime();
durMsgs.get().add(Integer.valueOf((int)(rqEnd-rqStart)));
outMsgs.incrementAndGet();
}
} else {
Request rq = (Request) request;
switch (rq.type) {
case OPEN_CELL_REQUEST: {
assert (rq.acceptors != null);
try {
proposer.openCell(rq.cellId, rq.acceptors, rq.requestME, rq.viewId);
acceptor.setViewId(rq.cellId, rq.viewId);
if (rq.listener != null)
rq.listener.proposalResult(rq.cellId, null, 0, FleaseMessage.IGNORE_MASTER_EPOCH);
} catch (FleaseException ex) {
Logging.logError(Logging.LEVEL_DEBUG, this, ex);
leaseListener.leaseFailed(rq.cellId, ex);
}
break;
}
case CLOSE_CELL_REQUEST: {
proposer.closeCell(rq.cellId);
rq.listener.proposalResult(rq.cellId, null, 0, FleaseMessage.IGNORE_MASTER_EPOCH);
break;
}
case HANDOVER_LEASE: {
try {
Flease prevLease = proposer.updatePrevLeaseForCell(rq.cellId, Flease.EMPTY_LEASE);
if (prevLease != null) {
//cancel the lease
leaseTimeouts.remove(prevLease);
}
proposer.handoverLease(rq.cellId, rq.newLeaseOwner);
} catch (FleaseException ex) {
rq.listener.proposalFailed(rq.cellId, ex);
}
break;
}
case SET_VIEW: {
proposer.setViewId(rq.cellId, rq.viewId);
acceptor.setViewId(rq.cellId, rq.viewId);
rq.listener.proposalResult(rq.cellId, null, 0, FleaseMessage.IGNORE_MASTER_EPOCH);
break;
}
case GET_STATE: {
try {
rq.cback.localStateResult(acceptor.localState());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
if (COLLECT_STATISTICS) {
long rqEnd = System.nanoTime();
durRequests.get().add(Integer.valueOf((int)(rqEnd-rqStart)));
}
}
}
if (DISABLE_RENEW_FOR_TESTING) {
Thread.sleep(0, 2);
}
} catch (InterruptedException ex) {
if (quit) {
break;
}
} catch (Throwable ex) {
notifyCrashed(ex);
break;
}
}
acceptor.shutdown();
notifyStopped();
Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this, "Flease stopped", FLEASE_VERSION);
}
public void shutdown() {
if (COLLECT_STATISTICS)
statThr.shutdown();
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "received shutdown call...");
quit = true;
this.interrupt();
}
private int checkTimers() throws Throwable {
final long now = TimeSync.getLocalSystemTime();
TimerEntry e = timers.peek();
if (e == null) {
return TIMER_INTERVAL_IN_MS;
}
if (e.getScheduledTime() <= now + TIMER_INTERVAL_IN_MS) {
//execute timer
do {
e = timers.poll();
long rqStart;
if (COLLECT_STATISTICS) {
rqStart = System.nanoTime();
inTimers.incrementAndGet();
}
if (e.getScheduledTime() < now) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "event sent after deadline: %s", e.message);
}
e.getMessage().setSendTimestamp(TimeSync.getGlobalTime());
proposer.processMessage(e.getMessage());
if (COLLECT_STATISTICS) {
long rqEnd = System.nanoTime();
durTimers.get().add(Integer.valueOf((int)(rqEnd-rqStart)));
}
e = timers.peek();
if (e == null) {
return TIMER_INTERVAL_IN_MS;
}
} while (e.getScheduledTime() <= now + TIMER_INTERVAL_IN_MS);
return (int) (e.getScheduledTime() - now);
} else {
//tell how long we have to wait
return (int) (e.getScheduledTime() - now);
}
}
private void checkLeaseTimeouts() {
final long now = TimeSync.getGlobalTime();
final long deadline = now + TIMER_INTERVAL_IN_MS + TimeSync.getLocalRenewInterval()+config.getToNotification_ms();
Flease f = leaseTimeouts.peek();
if (f == null)
return;
if (f.getLeaseTimeout_ms() <= deadline) {
//execute timer
do {
f = leaseTimeouts.poll();
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"lease state change: %s timed out (old lease: %s)",f.getCellId(),f.toString());
}
proposer.updatePrevLeaseForCell(f.getCellId(), f.EMPTY_LEASE);
leaseListener.statusChanged(f.getCellId(), Flease.EMPTY_LEASE);
//create restart event
FleaseMessage restartEvt = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
restartEvt.setCellId(f.getCellId());
restartEvt.setProposalNo(proposer.getCurrentBallotNo(f.getCellId()));
createTimer(restartEvt, TimeSync.getLocalSystemTime() + config.getDMax());
f = leaseTimeouts.peek();
if (f == null) {
return;
}
} while (f.getLeaseTimeout_ms() <= deadline);
}
}
protected void createTimer(FleaseMessage msg, long timestamp) {
msg.validateMessage();
TimerEntry e = new TimerEntry(timestamp, msg);
timers.add(e);
}
int getInRequests() {
return this.inRequests.getAndSet(0);
}
int getInMessages() {
return this.inMsgs.getAndSet(0);
}
int getOutMessages() {
return this.outMsgs.getAndSet(0);
}
int getInTimers() {
return this.inTimers.getAndSet(0);
}
List<Integer> getRequestDurations() {
return durRequests.getAndSet(new LinkedList());
}
List<Integer> getMessageDurations() {
return durMsgs.getAndSet(new LinkedList());
}
List<Integer> getTimersDurations() {
return durTimers.getAndSet(new LinkedList());
}
@Override
public void enqueueMessage(FleaseMessage message) {
messages.add(message);
}
private final static class TimerEntry implements Comparable {
private final long scheduledTime;
private final FleaseMessage message;
public TimerEntry(long scheduledTime, FleaseMessage message) {
this.scheduledTime = scheduledTime;
this.message = message;
}
/**
* @return the scheduledTime
*/
public long getScheduledTime() {
return scheduledTime;
}
public FleaseMessage getMessage() {
return this.message;
}
public int compareTo(Object o) {
TimerEntry e2 = (TimerEntry) o;
return (int) (this.scheduledTime - e2.scheduledTime);
}
}
private final static class Request {
public boolean autoRenew;
public boolean requestME;
public enum RequestType {
OPEN_CELL_REQUEST,
CLOSE_CELL_REQUEST,
GET_LEASE_REQUEST,
RETURN_LEASE_REQUEST,
HANDOVER_LEASE,
GET_STATE,
SET_VIEW
};
public final RequestType type;
public ASCIIString cellId;
public ASCIIString newLeaseOwner; //< for handover only!
public List<InetSocketAddress> acceptors;
public FleaseListener listener;
public int viewId;
public FleaseStateCallback cback;
public Request(RequestType type) {
this.type = type;
}
}
private static interface FleaseStateCallback {
public void localStateResult(Map<ASCIIString, FleaseMessage> state);
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
import org.xtreemfs.foundation.flease.comm.tcp.TCPFleaseCommunicator;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
*
* @author bjko
*/
public class FleaseStats extends Thread {
public static final int INTERVAL_IN_MS = 1000;
private volatile boolean quit;
private final FleaseStage st;
private final PrintWriter out;
public FleaseStats(FleaseStage st, String logfile) throws IOException {
super("FStats");
this.st = st;
this.quit = false;
try {
out = new PrintWriter(logfile);
} catch (IOException ex) {
Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this,"cannot write to %s, due to %s",logfile,ex.toString());
ex.printStackTrace();
throw ex;
}
}
public void shutdown() {
quit = true;
this.interrupt();
}
public void run() {
long t = 0;
Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"collecting statistics");
do {
try {
try {
sleep(INTERVAL_IN_MS);
} catch (InterruptedException ex) {
Logging.logMessage(Logging.LEVEL_INFO, this,"interrupted");
break;
}
t += INTERVAL_IN_MS;
int inRq = st.getInRequests();
int inMsgs = st.getInMessages();
int outMsgs = st.getOutMessages();
int inTimers = st.getInTimers();
int tcpOut = TCPFleaseCommunicator.instance.getNumOut();
int tcpIn = TCPFleaseCommunicator.instance.getNumIn();
List<Integer> durRq = st.getRequestDurations();
List<Integer> durMsgs = st.getMessageDurations();
List<Integer> durTimers = st.getTimersDurations();
printValues(inRq, durRq,t,"R");
printValues(inMsgs, durMsgs,t,"M");
printValues2(inMsgs, outMsgs,t,"m");
printValues2(tcpIn, tcpOut,t,"x");
printValues(inTimers, durTimers,t,"T");
} catch (Throwable thr) {
Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this,thr.toString());
}
} while (!quit);
out.close();
Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"done");
}
void printValues(int numRq, List<Integer> durations, long t, String type) {
int p95_out = getP95(durations);
double outPerInterval = ((double)INTERVAL_IN_MS)/( ((double)p95_out) / 1e6);
double rho = ((double)numRq)/outPerInterval;
if (p95_out == 0) {
outPerInterval = 0;
rho = 0;
}
out.format("%10d %s %10.2f %10.2f %10.2f\n", t,type,(double)numRq,outPerInterval,rho);
}
void printValues2(int numRq, int numOut, long t, String type) {
double rho = ((double)numRq)/((double)numOut);
if (numOut == 0) {
rho = 0;
}
out.format("%10d %s %10.2f %10.2f %10.2f\n", t,type,(double)numRq,(double)numOut,rho);
}
int getP95(List<Integer> items) {
if (items.size() == 0)
return 0;
if (items.size() == 1)
return items.get(0);
Collections.sort(items);
int rank = ((int)Math.round(0.95*items.size()))-1;
return items.get(rank);
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
/**
*
* @author bjko
*/
public interface FleaseStatusListener {
public void statusChanged(ASCIIString cellId, Flease lease);
public void leaseFailed(ASCIIString cellId, FleaseException error);
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import org.xtreemfs.foundation.buffer.ASCIIString;
/**
* The view change listener is called whenever flease
* (proposor or acceptor) see a new viewId > current viewId
* @author bjko
*/
public interface FleaseViewChangeListenerInterface {
public void viewIdChangeEvent(ASCIIString cellId, int viewId);
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
/**
*
* @author bjko
*/
public interface MasterEpochHandlerInterface {
public void sendMasterEpoch(FleaseMessage response, Continuation callback);
public void storeMasterEpoch(FleaseMessage request, Continuation callback);
public static interface Continuation {
void processingFinished();
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.concurrent.LinkedBlockingQueue;
import org.xtreemfs.foundation.LRUCache;
import org.xtreemfs.foundation.LifeCycleThread;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.logging.Logging;
/**
*
* @author bjko
*/
public class SimpleMasterEpochHandler extends LifeCycleThread implements MasterEpochHandlerInterface {
public static final int MAX_EPOCH_CACHE_SIZE = 10000;
private final LinkedBlockingQueue<Request> requests;
private final LRUCache<ASCIIString,Long> epochs;
private final String directory;
public SimpleMasterEpochHandler(String directory) {
super("SimpleMEHandler");
requests = new LinkedBlockingQueue<Request>();
epochs = new LRUCache<ASCIIString, Long>(MAX_EPOCH_CACHE_SIZE);
this.directory = directory;
}
@Override
public void run() {
try {
notifyStarted();
do {
Request rq = requests.take();
switch (rq.type) {
case SEND: {
try {
Long epoch = epochs.get(rq.message.getCellId());
if (epoch == null) {
File f = new File(getFileName(rq.message.getCellId()));
if (f.exists()) {
RandomAccessFile raf = new RandomAccessFile(f, "r");
epoch = raf.readLong();
raf.close();
} else {
epoch = 0l;
}
epochs.put(rq.message.getCellId(),epoch);
Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.all, this, "sent %d", epoch);
}
rq.message.setMasterEpochNumber(epoch);
} catch (Exception ex) {
rq.message.setMasterEpochNumber(-1);
} finally {
try {
rq.callback.processingFinished();
} catch (Exception ex) {
Logging.logError(Logging.LEVEL_ERROR, this, ex);
}
}
break;
}
case STORE: {
try {
File f = new File(getFileName(rq.message.getCellId()));
RandomAccessFile raf = new RandomAccessFile(f, "rw");
raf.writeLong(rq.message.getMasterEpochNumber());
raf.getFD().sync();
raf.close();
Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.all, this, "stored %d",
rq.message.getMasterEpochNumber());
epochs.put(rq.message.getCellId(),rq.message.getMasterEpochNumber());
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
rq.callback.processingFinished();
} catch (Exception ex) {
Logging.logError(Logging.LEVEL_ERROR, this, ex);
}
}
break;
}
}
} while (!interrupted());
} catch (InterruptedException ex) {
} catch (Throwable ex) {
notifyCrashed(ex);
}
notifyStopped();
}
private String getFileName(ASCIIString cellId) {
return directory + cellId.toString() + ".me";
}
@Override
public void shutdown() {
this.interrupt();
}
@Override
public void sendMasterEpoch(FleaseMessage response, Continuation callback) {
Request rq = new Request();
rq.callback = callback;
rq.message = response;
rq.type = Request.RequestType.SEND;
requests.add(rq);
}
@Override
public void storeMasterEpoch(FleaseMessage request, Continuation callback) {
Request rq = new Request();
rq.callback = callback;
rq.message = request;
rq.type = Request.RequestType.STORE;
requests.add(rq);
}
private final static class Request {
FleaseMessage message;
Continuation callback;
String fileName;
enum RequestType {
SEND, STORE;
};
RequestType type;
}
}

View File

@@ -0,0 +1,270 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.xtreemfs.foundation.LifeCycleThread;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
*
* @author bjko
*/
public class UDPFleaseCommunicator extends LifeCycleThread implements FleaseMessageSenderInterface {
private final FleaseStage stage;
private final int port;
private DatagramChannel channel;
private Selector selector;
private volatile boolean quit;
private final AtomicBoolean sendMode;
private final LinkedBlockingQueue<FleaseMessage> q;
private static final int MAX_UDP_SIZE = 16*1024;
private long numTx,numRx;
public UDPFleaseCommunicator(FleaseConfig config, String lockfileDir,
boolean ignoreLockForTesting,
final FleaseViewChangeListenerInterface viewListener) throws Exception {
super("FlUDPCom");
stage = new FleaseStage(config, lockfileDir, this, ignoreLockForTesting, viewListener, null, null);
port = config.getEndpoint().getPort();
q = new LinkedBlockingQueue<FleaseMessage>();
sendMode = new AtomicBoolean(false);
numTx = 0;
numRx = 0;
}
public FleaseStage getStage() {
return stage;
}
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
FleaseMessage m = message.clone();
m.setSender(recipient);
send(m);
}
/**
* sends a UDPRequest.
*
* @attention Overwrites the first byte of rq.data with the message type.
*/
public void send(FleaseMessage rq) {
q.add(rq);
if (q.size() == 1) {
//System.out.println("wakeup!");
selector.wakeup();
}
}
public void shutdown() {
quit = true;
interrupt();
}
@Override
public void run() {
long numRxCycles = 0;
long durAllRx = 0;
long maxPkgCycle = 0;
long avgPkgCycle = 0;
try {
selector = Selector.open();
channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(port));
channel.socket().setReceiveBufferSize(1024*1024*1024);
channel.socket().setSendBufferSize(1024*1024*1024);
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,"sendbuffer size: "+channel.socket().getSendBufferSize());
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,"recv size: "+channel.socket().getReceiveBufferSize());
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
if (Logging.isInfo())
Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "UDP socket on port %d ready",
port);
stage.start();
stage.waitForStartup();
notifyStarted();
boolean isRdOnly = true;
List<FleaseMessage> sendList = new ArrayList(5000);
ReusableBuffer data = BufferPool.allocate(MAX_UDP_SIZE);
while (!quit) {
if (q.size() == 0) {
if (!isRdOnly) {
channel.keyFor(selector).interestOps(SelectionKey.OP_READ);
//System.out.println("read only");
isRdOnly = true;
}
} else {
if (isRdOnly) {
channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
//System.out.println("read write");
isRdOnly = false;
}
}
int numKeys = selector.select();
if (q.size() == 0) {
if (!isRdOnly) {
channel.keyFor(selector).interestOps(SelectionKey.OP_READ);
//System.out.println("read only");
isRdOnly = true;
}
} else {
if (isRdOnly) {
channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
//System.out.println("read write");
isRdOnly = false;
}
}
if (numKeys == 0)
continue;
if (q.size() > 10000) {
System.out.println("QS!!!!! " + q.size());
System.out.println("is readOnly: " + isRdOnly);
}
// fetch events
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
// process all events
while (iter.hasNext()) {
SelectionKey key = iter.next();
// remove key from the list
iter.remove();
if (key.isWritable()) {
q.drainTo(sendList,50);
//System.out.println("sent: "+queue.size());
while (!sendList.isEmpty()) {
FleaseMessage r = sendList.remove(sendList.size()-1);
if (r == null)
break;
if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"sent packet to %s", r.getSender().toString());
data.clear();
r.serialize(data);
data.flip();
int sent = channel.send(data.getBuffer(), r.getSender());
if (sent == 0) {
System.out.println("cannot send anymore!");
q.addAll(sendList);
sendList.clear();
break;
}
numTx++;
}
}
if (key.isReadable()) {
InetSocketAddress sender = null;
int numRxInCycle = 0;
do {
data.clear();
sender = (InetSocketAddress) channel.receive(data.getBuffer());
if (sender == null) {
if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"read key for empty read");
break;
} else {
numRxInCycle++;
if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"read data from %s", sender.toString());
try {
//unpack flease message
data.flip();
FleaseMessage m = new FleaseMessage(data);
m.setSender(sender);
numRx++;
stage.receiveMessage(m);
} catch (Throwable ex) {
ex.printStackTrace();
Logging.logMessage(Logging.LEVEL_WARN, Category.net, this,
"received invalid UPD message: "+ex);
}
}
} while (sender != null);
numRxCycles++;
avgPkgCycle += numRxInCycle;
if (numRxInCycle > maxPkgCycle)
maxPkgCycle = numRxInCycle;
}
}
}
stage.shutdown();
selector.close();
channel.close();
} catch (ClosedByInterruptException ex) {
// ignore
} catch (IOException ex) {
Logging.logError(Logging.LEVEL_ERROR, this, ex);
} catch (Throwable th) {
notifyCrashed(th);
return;
}
Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this,"num packets tranferred: %d tx %d rx",numTx,numRx);
Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this,"numRxCycles %d, maxPkgPerCycle %d, avg/Cycle %d",numRxCycles,maxPkgCycle,avgPkgCycle/numRxCycles);
notifyStopped();
}
}

View File

@@ -0,0 +1,412 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.acceptor;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.FleaseConfig;
import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.comm.ProposalNumber;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
* Acceptor for MultiPaXos Lease negotiation (MPXLN).
* This version has no persistent state.
*
* @author bjko
*/
public class FleaseAcceptor {
/**
* Instances of the Multipaxos
*/
public final Map<ASCIIString, FleaseAcceptorCell> cells;
/**
* filename to use for storing state permanantly
*/
public static final String LOCKFILE_NAME = "flease_lock.";
/**
* lockfile full path
*/
private final String lockfile;
private final long waitUntilTimestamp_ms;
/**
* set to true to quit
*/
public boolean quit;
private final FleaseConfig config;
private FleaseViewChangeListenerInterface viewListener;
private final LearnEventListener evtListener;
/**
* Creates a new instance of PxAcceptor
*
* @param port
* port to listen on
* @param debug
*/
public FleaseAcceptor(LearnEventListener evtListener, FleaseConfig localConfig, String lockfileDir, boolean ignoreLockFileForTesting)
throws IOException {
this.config = localConfig;
cells = new HashMap<ASCIIString, FleaseAcceptorCell>();
quit = false;
lockfile = lockfileDir+"/"+LOCKFILE_NAME+config.getIdentity().hashCode();
this.evtListener = evtListener;
File lock = new File(lockfile);
if (lock.exists() && !ignoreLockFileForTesting) {
/*waitUntilTimestamp_ms = TimeSync.getLocalSystemTime()+TimeSync.getLocalRenewInterval()+
config.getRestartWait();*/
waitUntilTimestamp_ms = System.currentTimeMillis() + config.getRestartWait();
Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"restarted after crash (lock file %s exists). acceptor will ignore all messages for %d ms (recovery period until %s)",
lockfile,config.getRestartWait(),(new Date(waitUntilTimestamp_ms)).toString());
} else {
waitUntilTimestamp_ms = 0;
if (ignoreLockFileForTesting)
lock.delete();
if (!lock.createNewFile())
throw new IOException("Lock file exists!");
}
}
public void setViewChangeListener(FleaseViewChangeListenerInterface listener) {
viewListener = listener;
}
public void setViewId(ASCIIString cellId, int viewId) {
FleaseAcceptorCell cell = getCell(cellId);
// Set the viewId or invalidate the cell if the VIEW_ID_INVALIDATED is passed.
if (viewId == FleaseMessage.VIEW_ID_INVALIDATED) {
cell.invalidateView();
} else {
cell.setViewId(viewId);
}
}
private FleaseAcceptorCell getCell(FleaseMessage msg) {
assert (msg != null);
return getCell(msg.getCellId());
}
private FleaseAcceptorCell getCell(ASCIIString cellId) {
FleaseAcceptorCell cc = cells.get(cellId);
if (cc == null) {
cc = new FleaseAcceptorCell();
cells.put(cellId,cc);
} else {
if ((cc.lastAccess+config.getCellTimeout()) < System.currentTimeMillis()) {
if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A GCed cell "+cellId);
// Cell is outdated and GCed.
// Create a new cell and transfer the previous view.
FleaseAcceptorCell tmp = new FleaseAcceptorCell();
tmp.setViewId(cc.getViewId());
if (cc.isViewInvalidated()) {
tmp.invalidateView();
}
cells.put(cellId, tmp);
cc = tmp;
}
}
/*if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG,this,"using cell "+cellId);*/
cc.touch();
return cc;
}
/**
* Handles paxos prepare messages
*
* @param msg
* the incomming message
* @return a response message
*/
public FleaseMessage handlePREPARE(FleaseMessage msg) {
final FleaseAcceptorCell cc = getCell(msg);
cc.touch();
if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))) {
if (Logging.isDebug() && config.isDebugPrintMessages()) {
final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString();
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A prepare NACK p:"+preped+" is after "+msg.getProposalNo()+"");
}
FleaseMessage reject = new FleaseMessage(
FleaseMessage.MsgType.MSG_PREPARE_NACK,msg);
reject.setPrevProposalNo(cc.getPrepared().getProposalNo());
reject.setLeaseHolder(null);
reject.setLeaseTimeout(0);
reject.setSendTimestamp(TimeSync.getGlobalTime());
return reject;
} else {
if (Logging.isDebug() && config.isDebugPrintMessages()) {
final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString();
final String acced = (cc.getAccepted() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getAccepted().getProposalNo()+"="+cc.getAccepted().getLeaseHolder()+"/"+cc.getAccepted().getLeaseTimeout();
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A prepare ACK p:"+preped+" -> "+msg.getProposalNo()+" a:"+acced);
}
// lastPrepared = msg;
cc.setPrepared(msg);
// FIXME:Persistently write to disk
FleaseMessage response = new FleaseMessage(
FleaseMessage.MsgType.MSG_PREPARE_ACK,msg);
if (cc.getAccepted() != null) {
response.setPrevProposalNo(cc.getAccepted().getProposalNo());
response.setLeaseHolder(cc.getAccepted().getLeaseHolder());
assert(response.getLeaseHolder() != null);
response.setLeaseTimeout(cc.getAccepted()
.getLeaseTimeout());
}
response.setSendTimestamp(TimeSync.getGlobalTime());
return response;
}
}
/**
* Handles paxos accept (vote) messages.
*
* @param msg
* incomming message
* @return a response message or null
*/
public FleaseMessage handleACCEPT(FleaseMessage msg) {
final FleaseAcceptorCell cc = getCell(msg);
cc.touch();
if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))) {
// reject the request
if (Logging.isDebug() && config.isDebugPrintMessages()) {
final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString();
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A accept NACK p:"+preped+" is after "+msg.getProposalNo()+"");
}
FleaseMessage tmp = new FleaseMessage(
FleaseMessage.MsgType.MSG_ACCEPT_NACK,msg);
tmp.setSendTimestamp(TimeSync.getGlobalTime());
tmp.setLeaseHolder(null);
tmp.setLeaseTimeout(0);
tmp.setPrevProposalNo(cc.getPrepared().getProposalNo());
return tmp;
} else {
// okay accept it
if (Logging.isDebug() && config.isDebugPrintMessages()) {
final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString();
final String acced = (cc.getAccepted() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getAccepted().getProposalNo()+"="+cc.getAccepted().getLeaseHolder()+"/"+cc.getAccepted().getLeaseTimeout();
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A accept ACK p:"+preped+" a: "+acced+" -> "+msg.getProposalNo()+"="+msg.getLeaseHolder()+"/"+msg.getLeaseTimeout());
}
assert(msg.getLeaseHolder() != null);
cc.setAccepted(msg);
cc.setPrepared(msg);
FleaseMessage tmp = new FleaseMessage(
FleaseMessage.MsgType.MSG_ACCEPT_ACK,msg);
tmp.setSendTimestamp(TimeSync.getGlobalTime());
return tmp;
}
}
/**
* Handles paxos learn messages. Removes oudated instances and updates
* maxLearnedInstId accordingly
*
* @param msg
* incomming message
*/
public void handleLEARN(FleaseMessage msg) {
final FleaseAcceptorCell cc = getCell(msg);
cc.touch();
if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))
|| (cc.getAccepted() != null) && (cc.getAccepted().after(msg))) {
if (Logging.isDebug() && config.isDebugPrintMessages())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A ignore outdated LEARN message "+msg.getProposalNo());
} else {
if (Logging.isDebug() && config.isDebugPrintMessages()) {
final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString();
final String acced = (cc.getAccepted() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getAccepted().getProposalNo()+"="+cc.getAccepted().getLeaseHolder()+"/"+cc.getAccepted().getLeaseTimeout();
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A learn p:"+preped+" a: "+acced+" -> "+msg.getProposalNo()+"="+msg.getLeaseHolder()+"/"+msg.getLeaseTimeout());
}
cc.setAccepted(msg);
cc.setPrepared(msg);
cc.setLatestLearn(msg);
evtListener.learnedEvent(msg.getCellId(), msg.getLeaseHolder(), msg.getLeaseTimeout(), msg.getMasterEpochNumber());
}
}
/**
* Handles requests for lease information. Returns current lease
* holder+timeout or the current instance id.
*
* @param msg
* incomming message
* @return a response message
*/
public FleaseMessage getLocalLeaseInformation(ASCIIString cellId) {
FleaseAcceptorCell cc = getCell(cellId);
return cc.getLatestLearn();
}
public Map<ASCIIString,FleaseMessage> localState() {
Map<ASCIIString,FleaseMessage> state = new HashMap();
for (ASCIIString cellId : cells.keySet()) {
FleaseAcceptorCell cell = cells.get(cellId);
FleaseMessage lrn = null;
if (cell.isLearned())
lrn = cell.getAccepted();
state.put(cellId, lrn);
}
return state;
}
/**
* main loop
*/
public FleaseMessage processMessage(FleaseMessage msg) {
assert(!quit);
/*if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG,this,"received %s",msg.toString());*/
final long now = TimeSync.getLocalSystemTime();
if (msg.getSendTimestamp()+config.getMessageTimeout() < TimeSync.getGlobalTime()) {
//old message, ignore
if (Logging.isDebug() && config.isDebugPrintMessages())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"A outdated message discarded: %s",msg.toString());
return null;
}
if (this.waitUntilTimestamp_ms >= now) {
if (Logging.isDebug() && config.isDebugPrintMessages())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"A message discarded, acceptor is still in recovery period");
return null;
}
assert(msg.getCellId() != null);
final FleaseAcceptorCell cc = getCell(msg.getCellId());
if (cc.getViewId() < msg.getViewId()) {
// If the local view is lower than the delivered one, the view listener has to be informed to update
// the local view. But the request can still be answered.
viewListener.viewIdChangeEvent(msg.getCellId(), msg.getViewId());
} else if (cc.getViewId() > msg.getViewId() || (cc.getViewId() == msg.getViewId() && cc.isViewInvalidated())) {
// If the request is from an older view, or the a view that has been invalidated on this
// AcceptorCell, the request has to be aborted.
FleaseMessage response = new FleaseMessage(FleaseMessage.MsgType.MSG_WRONG_VIEW, msg);
response.setViewId(cc.getViewId());
return response;
}
FleaseMessage response = null;
if (msg.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE)
response = handlePREPARE(msg);
else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT)
response = handleACCEPT(msg);
else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_LEARN)
handleLEARN(msg);
/*else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_GET_LEASE)
response = handleGETLEASE(msg);
else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_RENEW_LEASE)
response = handleRENEWINSTANCE(msg);*/
else
Logging.logMessage(Logging.LEVEL_ERROR, Category.replication,this,"A invalid message type received: %s",msg.toString());
/*if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG,this,"response %s",(response != null) ? response.toString() : "<empty>");*/
return response;
}
/*private void notifyLeaseListener(FleaseAcceptorCell cell, ASCIIString leaseHolder, long leaseTimeout) {
if (leaseListener != null) {
final ASCIIString prevLeaseHolder = cell.getPrevLeaseHolder();
if ( ( (((prevLeaseHolder == null) || (leaseHolder == null)) && (prevLeaseHolder != leaseHolder)) ||
(!prevLeaseHolder.equals(leaseHolder)) ) || (leaseTimeout != cell.getPrevLeaseTimeout())) {
leaseListener.statusChanged(cell.getCellId(), leaseHolder,leaseTimeout);
cell.setPrevLeaseHolder(leaseHolder);
cell.setPrevLeaseTimeout(leaseTimeout);
}
}
}*/
/**
* string representation
*
* @return a string
*/
public String toString() {
return "Acceptor @ " + config.getIdentity();
}
// only for testing!
/*public String getLocalLeaseInfo(String cellId) {
synchronized (cells) {
FleaseAcceptorCell cc = getCell(cellId);
FleaseInstance currentL = cc.getInstances().get(cc.getMaxLearnedInstanceId());
if (currentL != null) {
// there is an instance
if (currentL.getAccepted().getLeaseTimeout() > (System
.currentTimeMillis() / 1000)
- config.getDMax()) {
return currentL.getAccepted().getLeaseHolder();
} else {
return null;
}
}
return null;
}
}*/
public void shutdown() {
this.quit = true;
File f = new File(lockfile);
f.delete();
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.acceptor;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicReference;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
/**
* A coordination cell is used to separate concurrent lease nogitiations
* for individual objects (e.g. volumes on the MRC).
* @author bjko
*/
public class FleaseAcceptorCell implements Serializable {
FleaseMessage prepared;
FleaseMessage accepted;
AtomicReference<FleaseMessage> latestLearn;
/** timestamp for last access **/
public long lastAccess;
private int viewId;
private boolean viewInvalidated = false;
/**
* Creates a new instance of CoordinationCell
*/
public FleaseAcceptorCell() {
prepared = null;
accepted = null;
lastAccess = TimeSync.getLocalSystemTime();
latestLearn = new AtomicReference<FleaseMessage>();
}
public FleaseMessage getLatestLearn() {
return latestLearn.get();
}
public void setLatestLearn(FleaseMessage msg) {
assert(msg.getMsgType() == FleaseMessage.MsgType.MSG_LEARN);
latestLearn.set(msg);
}
/**
* Getter for property lastPrep.
* @return Value of property lastPrep.
*/
public FleaseMessage getPrepared() {
return this.prepared;
}
/**
* Setter for property lastPrep.
* @param lastPrep New value of property lastPrep.
*/
public void setPrepared(FleaseMessage prepared) {
this.prepared = prepared;
}
/**
* Getter for property accepted.
* @return Value of property accepted.
*/
public FleaseMessage getAccepted() {
return this.accepted;
}
/**
* Setter for property accepted.
* @param accepted New value of property accepted.
*/
public void setAccepted(FleaseMessage accepted) {
assert(accepted.getLeaseHolder() != null);
assert(accepted.getLeaseTimeout() > 0);
this.accepted = accepted;
}
public boolean isLearned() {
return latestLearn.get() != null;
}
public void touch() {
this.lastAccess = System.currentTimeMillis();
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("\t");
sb.append("prep ");
sb.append(getPrepared());
sb.append("\n");
sb.append("\t");
sb.append("accept ");
sb.append(getAccepted());
sb.append("\n");
sb.append("\t");
sb.append("isLrnd ");
sb.append(isLearned());
sb.append("\n");
return sb.toString();
}
/**
* @return The most recently set viewId.
*/
public int getViewId() {
return viewId;
}
/**
* Set the acceptors viewId and clears the viewInvalidated flag.
*
* @param viewId
* The viewId to set.
*/
public void setViewId(int viewId) {
this.viewId = viewId;
this.viewInvalidated = false;
}
/**
* @return true if this view is invalidated.
*/
public boolean isViewInvalidated() {
return viewInvalidated;
}
/**
* Invalidate the current view.
*/
public void invalidateView() {
viewInvalidated = true;
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.acceptor;
import java.io.Serializable;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
/**
*
* @author bjko
*/
public class FleaseInstance implements Serializable {
/** Creates a new instance of PxInstance */
public FleaseInstance() {
learned = false;
timeout = 0;
prepared = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE);
accepted = null;
}
/**
* Holds value of property learned.
*/
private boolean learned;
/**
* Getter for property learned.
* @return Value of property learned.
*/
public boolean isLearned() {
return this.learned;
}
/**
* Setter for property learned.
* @param learned New value of property learned.
*/
public void setLearned(boolean learned) {
this.learned = learned;
}
/**
* Holds value of property timeout.
*/
private long timeout;
/**
* Getter for property timeout.
* @return Value of property timeout.
*/
public long getTimeout() {
return this.timeout;
}
/**
* Setter for property timeout.
* @param timeout New value of property timeout.
*/
public void setTimeout(long timeout) {
this.timeout = timeout;
}
/**
* Holds value of property prepared.
*/
private FleaseMessage prepared;
/**
* Getter for property lastPrep.
* @return Value of property lastPrep.
*/
public FleaseMessage getPrepared() {
return this.prepared;
}
/**
* Setter for property lastPrep.
* @param lastPrep New value of property lastPrep.
*/
public void setPrepared(FleaseMessage prepared) {
this.prepared = prepared;
}
/**
* Holds value of property accepted.
*/
private FleaseMessage accepted;
/**
* Getter for property accepted.
* @return Value of property accepted.
*/
public FleaseMessage getAccepted() {
return this.accepted;
}
/**
* Setter for property accepted.
* @param accepted New value of property accepted.
*/
public void setAccepted(FleaseMessage accepted) {
assert(accepted.getLeaseHolder() != null);
assert(accepted.getLeaseTimeout() > 0);
this.accepted = accepted;
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.acceptor;
import org.xtreemfs.foundation.buffer.ASCIIString;
/**
*
* @author bjko
*/
public interface LearnEventListener {
public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber);
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm;
import java.io.IOException;
import java.net.InetSocketAddress;
/**
*
* @author bjko
*/
public interface FleaseCommunicationInterface {
public void sendMessage(FleaseMessage msg, InetSocketAddress receiver) throws IOException;
public void requestTimer(FleaseMessage msg, long timestamp);
}

View File

@@ -0,0 +1,460 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.Date;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.flease.FleaseConfig;
/**
* A message for multipaxos lease negotiation.
* @author bjko
*/
public class FleaseMessage implements Serializable, Cloneable {
/**
* Message types
*/
public static enum MsgType {
/**
* paxos prepare message
*/
MSG_PREPARE,
/**
* acknowledgment for prepare
*/
MSG_PREPARE_ACK,
/**
* reject of prepare
*/
MSG_PREPARE_NACK,
/**
* paxos vote message
*/
MSG_ACCEPT,
/**
* acceptance of vote (voted)
*/
MSG_ACCEPT_ACK,
/**
* reject of vote message
*/
MSG_ACCEPT_NACK,
/**
* paxos learn message
*/
MSG_LEARN,
/**
* for future use (volontary lease return by master, revocation)
*/
MSG_LEASE_RETURN,
/**
* internal timeout event during prepare (timer)
*/
EVENT_TIMEOUT_PREPARE,
/**
* internal timeout event during prepare (timer)
*/
EVENT_TIMEOUT_ACCEPT,
/**
* internal restart event (timer)
*/
EVENT_RESTART,
/**
* event to renew the lease
*/
EVENT_RENEW,
/**
* message (response) indicating that the viewId has changed
*/
MSG_WRONG_VIEW
};
private static final long serialVersionUID = 3187504351237849866L;
public static final int VIEW_ID_INVALIDATED = -1;
public static final long IGNORE_MASTER_EPOCH = -1;
public static final long REQUEST_MASTER_EPOCH = 0;
/**
* message type
* @see MsgType
*/
private final MsgType msgType;
/**
* cellId this message belongs to
*/
private ASCIIString cellId;
/**
* proposal number for this message
*/
private ProposalNumber proposalNo;
/**
* timestamp when the message was sent to discard messages arriving after
* timeout+dmax.
*/
private long sendTimestamp;
/**
* the socket address of the current lease holder
* part of the proposal value
* @attention necessary for correct operation of leases negotiation
*/
private ASCIIString leaseHolder;
/**
* (absolute) timestamp of lease timeout in ms since epoch
* part of the proposal value
* @attention necessary for correct operation of leases negotiation
*/
private long leaseTimeout;
private ProposalNumber prevProposalNo;
private InetSocketAddress address;
private int viewId;
private long masterEpochNumber;
/**
* Creates a new instance of PxMessage
* @param msgType message type
*/
public FleaseMessage(MsgType msgType) {
this.msgType = msgType;
this.proposalNo = ProposalNumber.EMPTY_PROPOSAL_NUMBER;
this.prevProposalNo = ProposalNumber.EMPTY_PROPOSAL_NUMBER;
this.masterEpochNumber = IGNORE_MASTER_EPOCH;
}
/**
* Creates a new instance of PxMessage
* @param msgType message type
* @param template a message to take instanceId and cellId from
*/
public FleaseMessage(MsgType msgType, FleaseMessage template) {
this.msgType = msgType;
this.proposalNo = template.proposalNo;
this.cellId = template.cellId;
this.leaseHolder = template.leaseHolder;
this.leaseTimeout = template.leaseTimeout;
this.prevProposalNo = template.prevProposalNo;
this.viewId = template.viewId;
this.masterEpochNumber = template.masterEpochNumber;
}
public FleaseMessage(FleaseMessage other) {
this.msgType = other.msgType;
this.address = other.address;
this.proposalNo = other.proposalNo;
this.cellId = other.cellId;
this.leaseHolder = other.leaseHolder;
this.leaseTimeout = other.leaseTimeout;
this.sendTimestamp = other.sendTimestamp;
this.prevProposalNo = other.prevProposalNo;
this.viewId = other.viewId;
this.masterEpochNumber = other.masterEpochNumber;
}
public void validateMessage() {
assert(msgType != null);
assert(proposalNo != null);
assert(cellId != null);
}
/**
* @return the prevAcceptedBallotNo
*/
public ProposalNumber getPrevProposalNo() {
return prevProposalNo;
}
/**
* @param prevAcceptedBallotNo the prevAcceptedBallotNo to set
*/
public void setPrevProposalNo(ProposalNumber prevAcceptedBallotNo) {
this.prevProposalNo = prevAcceptedBallotNo;
}
/**
* @return the viewId
*/
public int getViewId() {
return viewId;
}
/**
* @param viewId the viewId to set
*/
public void setViewId(int viewId) {
this.viewId = viewId;
}
/**
* @return the masterEpochNumber
*/
public long getMasterEpochNumber() {
return masterEpochNumber;
}
/**
* @param masterEpochNumber the masterEpochNumber to set
*/
public void setMasterEpochNumber(long masterEpochNumber) {
this.masterEpochNumber = masterEpochNumber;
}
/**
* Getter for property proposalNo.
* @return Value of property proposalNo.
*/
public ProposalNumber getProposalNo() {
return this.proposalNo;
}
/**
* Setter for property proposalNo.
* @param proposalNo New value of property proposalNo.
*/
public void setProposalNo(ProposalNumber proposalNo) {
this.proposalNo = proposalNo;
}
/**
* Getter for property msgType.
* @return Value of property msgType.
*/
public MsgType getMsgType() {
return this.msgType;
}
/**
* Setter for property msgType.
* @param msgType New value of property msgType.
*/
/*public void setMsgType(MsgType msgType) {
this.msgType = msgType;
}*/
/**
* Getter for property leaseHolder.
* @return Value of property leaseHolder.
*/
public ASCIIString getLeaseHolder() {
return this.leaseHolder;
}
/**
* Setter for property leaseHolder.
* @param leaseHolder New value of property leaseHolder.
*/
public void setLeaseHolder(ASCIIString leaseHolder) {
this.leaseHolder = leaseHolder;
}
/**
* Getter for property leaseTimeout.
* @return Value of property leaseTimeout.
*/
public long getLeaseTimeout() {
return this.leaseTimeout;
}
/**
* Setter for property leaseTimeout.
* @param leaseTimeout New value of property leaseTimeout.
*/
public void setLeaseTimeout(long leaseTimeout) {
this.leaseTimeout = leaseTimeout;
}
/**
* Getter for property cellId.
* @return Value of property cellId.
*/
public ASCIIString getCellId() {
return this.cellId;
}
/**
* Setter for property cellId.
* @param cellId New value of property cellId.
*/
public void setCellId(ASCIIString cellId) {
this.cellId = cellId;
}
/**
* @return the sendTimestamp
*/
public long getSendTimestamp() {
return sendTimestamp;
}
/**
* @param sendTimestamp the sendTimestamp to set
*/
public void setSendTimestamp(long sendTimestamp) {
this.sendTimestamp = sendTimestamp;
}
/**
* @return the sender
*/
public InetSocketAddress getSender() {
return address;
}
/**
* @param sender the sender to set
*/
public void setSender(InetSocketAddress sender) {
this.address = sender;
}
/**
* checks if this message is before other
* @param other another message
* @return true if this message is before other
*/
public boolean before(FleaseMessage other) {
return proposalNo.before(other.proposalNo);
}
/**
* checks if this message is after other
* @param other another message
* @return true if this message is after (i.e. >) other
*/
public boolean after(FleaseMessage other) {
return proposalNo.after(other.proposalNo);
}
/**
* checks if both messages have the same message id.
* @param other another message
* @return true if both messages have the same message id
*/
public boolean sameMsgId(FleaseMessage other) {
return proposalNo.sameNumber(other.proposalNo);
}
/**
* toString
* @return a string representation of the message
*/
@Override
public String toString() {
assert(this.msgType != null);
return String.format("FleaseMessage ( type=%s cell=%s v=%d b=%s lease=%s/%d(%s) prevb=%s ts=%d(%s) addr=%s mepoch=%d)",
this.msgType.toString(),this.cellId,this.viewId,this.proposalNo,this.leaseHolder,
this.leaseTimeout,new Date(this.leaseTimeout),this.prevProposalNo,this.sendTimestamp,new Date(this.sendTimestamp),
(address != null) ? address.toString() : "n/a", this.masterEpochNumber);
}
public boolean isInternalEvent() {
return msgType == MsgType.EVENT_RESTART ||
msgType == MsgType.EVENT_TIMEOUT_ACCEPT ||
msgType == MsgType.EVENT_TIMEOUT_PREPARE;
}
public boolean isAcceptorMessage() {
return msgType == MsgType.MSG_ACCEPT ||
msgType == MsgType.MSG_LEARN ||
msgType == MsgType.MSG_PREPARE ||
msgType == MsgType.MSG_LEASE_RETURN;
}
public boolean isProposerMessage() {
return msgType == MsgType.MSG_ACCEPT_ACK ||
msgType == MsgType.MSG_ACCEPT_NACK ||
msgType == MsgType.MSG_PREPARE_ACK ||
msgType == MsgType.MSG_PREPARE_NACK;
}
public int getSize() {
return 1+cellId.getSerializedSize()+
(leaseHolder == null ? 4 : leaseHolder.getSerializedSize())+
8+8+8+8+8+8+4+8;
}
public void serialize(ReusableBuffer buffer) {
assert(buffer != null);
buffer.put((byte)this.msgType.ordinal());
cellId.marshall(buffer);
proposalNo.serialize(buffer);
prevProposalNo.serialize(buffer);
buffer.putLong(this.getSendTimestamp());
buffer.putLong(this.leaseTimeout);
if (leaseHolder != null)
this.leaseHolder.marshall(buffer);
else
buffer.putInt(0);
buffer.putInt(this.viewId);
buffer.putLong(this.masterEpochNumber);
}
public FleaseMessage(ReusableBuffer buffer) {
assert(buffer != null);
this.msgType = MsgType.values()[buffer.get()];
this.cellId = ASCIIString.unmarshall(buffer);
this.proposalNo = new ProposalNumber(buffer);
this.prevProposalNo = new ProposalNumber(buffer);
this.setSendTimestamp(buffer.getLong());
this.leaseTimeout = buffer.getLong();
this.leaseHolder = ASCIIString.unmarshall(buffer);
this.viewId = buffer.getInt();
this.masterEpochNumber = buffer.getLong();
}
public boolean hasTimedOut(FleaseConfig cfg, long currentGlobalTimeout) {
assert(this.leaseTimeout > 0);
assert(this.leaseHolder != null);
return (this.leaseTimeout+cfg.getDMax() < currentGlobalTimeout);
}
public boolean hasNotTimedOut(FleaseConfig cfg, long currentGlobalTimeout) {
assert(this.leaseTimeout > 0);
assert(this.leaseHolder != null);
return (this.leaseTimeout-cfg.getDMax() > currentGlobalTimeout);
}
@Override
public FleaseMessage clone() {
FleaseMessage myClone = new FleaseMessage(this);
myClone.address = this.address;
myClone.cellId = this.cellId;
myClone.leaseHolder = this.leaseHolder;
myClone.leaseTimeout = this.leaseTimeout;
myClone.prevProposalNo = this.prevProposalNo;
myClone.proposalNo = this.proposalNo;
myClone.sendTimestamp = this.sendTimestamp;
myClone.viewId = this.viewId;
myClone.masterEpochNumber = this.masterEpochNumber;
return myClone;
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
/**
*
* @author bjko
*/
public class ProposalNumber implements Cloneable {
private final long proposalNo;
private final long senderId;
public static final ProposalNumber EMPTY_PROPOSAL_NUMBER = new ProposalNumber(0, 0);
public ProposalNumber(long proposalNo, long senderId) {
this.proposalNo = proposalNo;
this.senderId = senderId;
}
public ProposalNumber(ReusableBuffer buffer) {
this.proposalNo = buffer.getLong();
this.senderId = buffer.getLong();
}
/**
* checks if this message is before other
* @param other another message
* @return true if this message is before other
*/
public boolean before(ProposalNumber other) {
if (this.proposalNo < other.proposalNo) {
return true;
} else if (this.proposalNo > other.proposalNo) {
return false;
} else {
return (this.senderId < other.senderId);
}
}
/**
* checks if this message is after other
* @param other another message
* @return true if this message is after (i.e. >) other
*/
public boolean after(ProposalNumber other) {
if (this.proposalNo > other.proposalNo) {
return true;
} else if (this.proposalNo < other.proposalNo) {
return false;
} else {
return (this.senderId > other.senderId);
}
}
public boolean sameNumber(ProposalNumber other) {
return (senderId == other.senderId)&& (proposalNo == other.proposalNo);
}
public boolean isEmpty() {
if (this == EMPTY_PROPOSAL_NUMBER)
return true;
return this.sameNumber(EMPTY_PROPOSAL_NUMBER);
}
public void serialize(ReusableBuffer buffer) {
buffer.putLong(this.proposalNo);
buffer.putLong(this.senderId);
}
/**
* @return the proposalNo
*/
public long getProposalNo() {
return proposalNo;
}
/**
* @return the senderId
*/
public long getSenderId() {
return senderId;
}
public String toString() {
return "("+proposalNo+";"+senderId+")";
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.logging.Logging;
/**
*
* @author bjko
*/
public class EchoClient {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Logging.start(Logging.LEVEL_DEBUG);
TimeSync ts = TimeSync.initializeLocal(50);
try {
ts.waitForStartup();
TCPClient com = new TCPClient(3334,null, new NIOServer() {
public void onAccept(NIOConnection connection) {
onConnect(connection);
}
public void onConnect(NIOConnection connection) {
System.out.println("connected to "+connection.getEndpoint());
connection.read(BufferPool.allocate(1024));
connection.setContext(new AtomicBoolean(false));
}
public void onRead(NIOConnection connection, ReusableBuffer buffer) {
System.out.println("read from "+connection);
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
String contents = new String(data);
BufferPool.free(buffer);
connection.read(BufferPool.allocate(1024));
System.out.println(">> "+contents);
}
public void onClose(NIOConnection connection) {
System.out.println("connection from "+connection.getEndpoint()+" closed ");
}
public void onWriteFailed(IOException exception, Object context) {
System.out.println("could not write, context: "+context);
}
public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) {
System.out.println("could not connect to: "+endpoint+", context: "+context);
}
});
com.start();
com.waitForStartup();
ReusableBuffer data = ReusableBuffer.wrap("Hello world!\n".getBytes());
com.write(new InetSocketAddress("localhost", 3333), data, "Yagg");
Thread.sleep(100);
data = ReusableBuffer.wrap("Hello world!\n".getBytes());
com.write(new InetSocketAddress("localhost", 3333), data, "Yagga");
Thread.sleep(30000);
data = ReusableBuffer.wrap("YaggaYagga!\n".getBytes());
com.write(new InetSocketAddress("localhost", 3333), data, null);
Thread.sleep(2000);
com.shutdown();
ts.close();
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.logging.Logging;
/**
*
* @author bjko
*/
public class EchoServer implements NIOServer {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try {
Logging.start(Logging.LEVEL_DEBUG);
TimeSync.initializeLocal(50);
EchoServer s = new EchoServer();
TCPCommunicator srv = new TCPCommunicator(s, 3333, null);
srv.start();
srv.waitForStartup();
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
public EchoServer() {
}
public void onAccept(NIOConnection connection) {
//ignore
System.out.println("connected: "+connection);
connection.read(BufferPool.allocate(1024));
}
public void onConnect(NIOConnection connection) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void onRead(NIOConnection connection, ReusableBuffer buffer) {
boolean done = false;
System.out.println("do read: "+connection);
for (int i = 0; i < buffer.position(); i++) {
if (buffer.get(i) == '\n') {
done = true;
break;
}
}
if (done || !buffer.hasRemaining()) {
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
String contents = new String(data);
if (contents.startsWith("quit")) {
try {
connection.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
//we have a full line
System.out.println("new buffer: "+connection);
buffer.clear();
if (contents.startsWith("stats")) {
contents = BufferPool.getStatus();
} else {
contents = "you said: "+contents;
}
buffer.put(contents.getBytes());
buffer.flip();
connection.write(buffer,null);
connection.read(BufferPool.allocate(1024));
}
}
}
public void onClose(NIOConnection connection) {
System.out.println("disconnected: "+connection);
}
public void onWriteFailed(IOException exception, Object context) {
System.out.println("an error occurred: "+exception);
}
public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) {
//ignore
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.net.InetSocketAddress;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
/**
*
* @author bjko
*/
public class NIOConnection {
private TCPConnection connection;
private Object context;
public NIOConnection(TCPConnection connection) {
this.connection = connection;
}
public void setContext(Object context) {
this.context = context;
}
public Object getContext() {
return context;
}
/**
* READ MUST ONLY BE USED FROM A NIOServer callback!
* @param buffer
*/
public void read(ReusableBuffer buffer) {
connection.setReceiveBuffer(buffer);
}
/**
* Write is thread safe
* @param buffer
*/
public void write(ReusableBuffer buffer, Object context) {
connection.getServer().write(connection, buffer, context);
//FIXME:wakeup selector, change interest set
}
public void close() {
connection.getServer().closeConnection(connection);
}
public InetSocketAddress getEndpoint() {
return connection.getEndpoint();
}
public String toString() {
return "TCP connection (from "+connection.getChannel().socket().getRemoteSocketAddress()+" to local server @ "+connection.getServer().getPort()+")";
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
/**
*
* @author bjko
*/
public interface NIOServer {
/**
* called upon incoming connections.
* @param connection
*/
public void onAccept(NIOConnection connection);
/**
* called when a connection was established
* make sure to issue the first write
* @param connection
*/
public void onConnect(NIOConnection connection);
/**
* called when new data is available
* @param connection
* @param buffer
*/
public void onRead(NIOConnection connection, ReusableBuffer buffer);
/**
* called when a connection is closed
* @param connection
*/
public void onClose(NIOConnection connection);
public void onWriteFailed(IOException exception, Object context);
public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context);
}

View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.xtreemfs.foundation.LifeCycleListener;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.logging.Logging;
/**
*
* @author bjko
*/
public class TCPClient {
private static final long MAX_WAITTIME_MS = 1000 * 60 * 10;
final Map<InetSocketAddress, ClientConnection> connections;
final ReadWriteLock conLock;
final TCPCommunicator server;
final NIOServer implementation;
final Timer closeTimer;
public TCPClient(int port, InetAddress bindAddr, final NIOServer implementation) throws IOException {
conLock = new ReentrantReadWriteLock();
connections = new HashMap();
this.implementation = implementation;
NIOServer impl = new NIOServer() {
public void onAccept(NIOConnection connection) {
final InetSocketAddress endpt = connection.getEndpoint();
try {
conLock.writeLock().lock();
ClientConnection cc = connections.get(endpt);
if (cc == null) {
cc = new ClientConnection();
cc.setConnection(connection);
cc.connectSucces();
connections.put(endpt,cc);
}
} finally {
conLock.writeLock().unlock();
}
implementation.onAccept(connection);
}
public void onConnect(NIOConnection connection) {
final InetSocketAddress endpt = connection.getEndpoint();
try {
conLock.writeLock().lock();
ClientConnection cc = connections.get(endpt);
if (cc != null)
cc.connectSucces();
else {
Logging.logMessage(Logging.LEVEL_ERROR, this,"connect for unknown connection: "+connection);
connection.close();
}
} finally {
conLock.writeLock().unlock();
}
implementation.onConnect(connection);
}
public void onRead(NIOConnection connection, ReusableBuffer buffer) {
implementation.onRead(connection, buffer);
}
public void onClose(NIOConnection connection) {
final InetSocketAddress endpt = connection.getEndpoint();
try {
conLock.writeLock().lock();
connections.remove(endpt);
} finally {
conLock.writeLock().unlock();
}
implementation.onClose(connection);
}
public void onWriteFailed(IOException exception, Object context) {
implementation.onWriteFailed(exception, context);
}
public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) {
System.out.println("connect failed for: "+endpoint);
try {
conLock.readLock().lock();
ClientConnection cc = connections.get(endpoint);
if (cc != null) {
synchronized (cc) {
cc.connectFailed();
cc.setConnection(null);
}
}
} finally {
conLock.readLock().unlock();
}
implementation.onConnectFailed(endpoint,exception,context);
}
};
server = new TCPCommunicator(impl, port, bindAddr);
closeTimer = new Timer();
/*closeTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
final long now = TimeSync.getLocalSystemTime();
try {
conLock.writeLock().lock();
for (Entry<InetSocketAddress,ClientConnection> e : connections.entrySet()) {
if (e.getValue().lastConnectAttempt_ms)
}
} finally {
conLock.writeLock().unlock();
}
}
}, CON_TIMEOUT, CON_TIMEOUT);
*/
}
public void write(InetSocketAddress remote, ReusableBuffer data, Object context) {
ClientConnection client = null;
try {
conLock.readLock().lock();
client = connections.get(remote);
} finally {
conLock.readLock().unlock();
}
if (client == null) {
try {
conLock.writeLock().lock();
client = connections.get(remote);
if (client == null) {
client = new ClientConnection();
connections.put(remote, client);
}
} finally {
conLock.writeLock().unlock();
}
}
synchronized (client) {
try {
if (!client.isConnected()) {
if (client.canReconnect()) {
NIOConnection con = server.connect(remote,null);
client.setConnection(con);
} else {
implementation.onWriteFailed(new IOException("cannot connect to server, blocked due to reconnect timeout"), context);
return;
}
}
} catch (IOException ex) {
implementation.onWriteFailed(ex, context);
return;
}
assert(client.getConnection() != null);
client.getConnection().write(data, context);
}
}
public void start() {
server.start();
}
public void waitForStartup() throws Exception {
server.waitForStartup();
}
public void shutdown() {
server.shutdown();
closeTimer.cancel();
}
public void waitForShutdown() throws Exception {
server.waitForShutdown();
}
public void setLifeCycleListener(LifeCycleListener l) {
server.setLifeCycleListener(l);
}
public int getSendQueueSize() {
return server.getSendQueueSize();
}
private static class ClientConnection {
NIOConnection connection;
long lastConnectAttempt_ms;
long waitTime_ms;
public ClientConnection() {
lastConnectAttempt_ms = 0;
waitTime_ms = 1000;
}
public NIOConnection getConnection() {
return connection;
}
public void setConnection(NIOConnection connection) {
this.connection = connection;
}
public boolean canReconnect() {
return (lastConnectAttempt_ms + waitTime_ms < TimeSync.getLocalSystemTime());
}
public boolean isConnected() {
return (connection != null);
}
public void connectSucces() {
waitTime_ms = 1000;
lastConnectAttempt_ms = 0;
}
public void connectFailed() {
lastConnectAttempt_ms = TimeSync.getLocalSystemTime();
waitTime_ms = waitTime_ms * 2;
if (waitTime_ms > MAX_WAITTIME_MS) {
waitTime_ms = MAX_WAITTIME_MS;
}
}
}
}

View File

@@ -0,0 +1,557 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import org.xtreemfs.foundation.LifeCycleThread;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.flease.comm.tcp.TCPConnection.SendRequest;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
*
* @author bjko
*/
public class TCPCommunicator extends LifeCycleThread {
private final int port;
/**
* the server socket
*/
private final ServerSocketChannel socket;
/**
* Selector for server socket
*/
private final Selector selector;
private final NIOServer implementation;
private final List<TCPConnection> connections;
private final Queue<TCPConnection> pendingCons;
private final AtomicInteger sendQueueSize;
/**
*
* @param implementation
* @param port, 0 to disable server mode
* @param bindAddr
* @throws IOException
*/
public TCPCommunicator(NIOServer implementation, int port, InetAddress bindAddr) throws IOException {
super("TCPcom@" + port);
this.port = port;
this.implementation = implementation;
this.connections = new LinkedList();
this.pendingCons = new ConcurrentLinkedQueue();
sendQueueSize = new AtomicInteger();
// open server socket
if (port == 0) {
socket = null;
} else {
socket = ServerSocketChannel.open();
socket.configureBlocking(false);
socket.socket().setReceiveBufferSize(256 * 1024);
socket.socket().setReuseAddress(true);
socket.socket().bind(
bindAddr == null ? new InetSocketAddress(port) : new InetSocketAddress(bindAddr, port));
}
// create a selector and register socket
selector = Selector.open();
if (socket != null)
socket.register(selector, SelectionKey.OP_ACCEPT);
}
/**
* Stop the server and close all connections.
*/
public void shutdown() {
this.interrupt();
}
/**
* sends a response.
*
* @param request
* the request
*/
public void write(TCPConnection connection, ReusableBuffer buffer, Object context) {
assert (buffer != null);
synchronized (connection) {
if (connection.getChannel().isConnected()) {
if (connection.sendQueueIsEmpty()) {
try {
int bytesWritten = connection.getChannel().write(buffer.getBuffer());
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this,"directly wrote %d bytes to %s",bytesWritten,connection.getChannel().socket().getRemoteSocketAddress().toString());
}
if (bytesWritten < 0) {
if (context != null)
implementation.onWriteFailed(new IOException("remote party closed connection while writing"), context);
abortConnection(connection,new IOException("remote party closed connection while writing"));
return;
}
if (!buffer.hasRemaining()) {
//we are done
BufferPool.free(buffer);
return;
}
} catch (ClosedChannelException ex) {
if (context != null)
implementation.onWriteFailed(ex, context);
abortConnection(connection,ex);
} catch (IOException ex) {
if (Logging.isDebug())
Logging.logError(Logging.LEVEL_DEBUG, this,ex);
if (context != null)
implementation.onWriteFailed(ex, context);
abortConnection(connection,ex);
}
}
synchronized (connection) {
boolean isEmpty = connection.sendQueueIsEmpty();
if (isEmpty) {
try {
SelectionKey key = connection.getChannel().keyFor(selector);
if (key != null) {
key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
}
} catch (CancelledKeyException ex) {
}
}
}
sendQueueSize.incrementAndGet();
connection.addToSendQueue(new TCPConnection.SendRequest(buffer, context));
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this,"enqueued write to %s",connection.getEndpoint());
}
selector.wakeup();
} else {
// ignore and free bufers
if (connection.getChannel().isConnectionPending()) {
sendQueueSize.incrementAndGet();
connection.addToSendQueue(new TCPConnection.SendRequest(buffer, context));
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this,"enqueued write to %s",connection.getEndpoint());
}
} else {
BufferPool.free(buffer);
if (context != null)
implementation.onWriteFailed(new IOException("Connection already closed"), context);
}
}
}
}
public void run() {
notifyStarted();
if (Logging.isInfo()) {
Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "TCP Server @%d ready", port);
}
try {
while (!isInterrupted()) {
// try to select events...
try {
final int numKeys = selector.select();
if (!pendingCons.isEmpty()) {
while (true) {
TCPConnection con = pendingCons.poll();
if (con == null) {
break;
}
try {
assert(con.getChannel() != null);
con.getChannel().register(selector,
SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE | SelectionKey.OP_READ, con);
} catch (ClosedChannelException ex) {
abortConnection(con,ex);
}
}
}
if (numKeys == 0) {
continue;
}
} catch (CancelledKeyException ex) {
// who cares
} catch (IOException ex) {
Logging.logMessage(Logging.LEVEL_WARN, Category.net, this,
"Exception while selecting: %s", ex.toString());
continue;
}
// fetch events
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
// process all events
while (iter.hasNext()) {
SelectionKey key = iter.next();
// remove key from the list
iter.remove();
try {
if (key.isAcceptable()) {
acceptConnection(key);
}
if (key.isConnectable()) {
connectConnection(key);
}
if (key.isReadable()) {
readConnection(key);
}
if (key.isWritable()) {
writeConnection(key);
}
} catch (CancelledKeyException ex) {
// nobody cares...
continue;
}
}
}
for (TCPConnection con : connections) {
try {
con.close(implementation,new IOException("server shutdown"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
// close socket
selector.close();
if (socket != null)
socket.close();
if (Logging.isInfo()) {
Logging.logMessage(Logging.LEVEL_INFO, Category.net, this,
"TCP Server @%d shutdown complete", port);
}
notifyStopped();
} catch (Throwable thr) {
Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, "TPC Server @%d CRASHED!", port);
notifyCrashed(thr);
}
}
private void connectConnection(SelectionKey key) {
final TCPConnection con = (TCPConnection) key.attachment();
final SocketChannel channel = con.getChannel();
try {
if (channel.isConnectionPending()) {
channel.finishConnect();
}
synchronized (con) {
if (con.getSendBuffer() != null) {
key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ);
} else {
key.interestOps(SelectionKey.OP_READ);
}
}
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connected from %s to %s", con
.getChannel().socket().getLocalSocketAddress().toString(), channel.socket().getRemoteSocketAddress()
.toString());
}
implementation.onConnect(con.getNIOConnection());
} catch (IOException ex) {
if (Logging.isDebug()) {
Logging.logError(Logging.LEVEL_DEBUG, this,ex);
}
implementation.onConnectFailed(con.getEndpoint(), ex, con.getNIOConnection().getContext());
con.close(implementation,ex);
}
}
public NIOConnection connect(InetSocketAddress server, Object context) throws IOException {
TCPConnection con = openConnection(server,context);
return con.getNIOConnection();
}
private TCPConnection openConnection(InetSocketAddress server, Object context) throws IOException {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connect to %s", server
.toString());
}
SocketChannel channel = null;
TCPConnection con = null;
try {
channel = SocketChannel.open();
channel.configureBlocking(false);
//channel.socket().setTcpNoDelay(true);
channel.socket().setReceiveBufferSize(256 * 1024);
channel.connect(server);
con = new TCPConnection(channel, this, server);
con.getNIOConnection().setContext(context);
pendingCons.add(con);
selector.wakeup();
if (Logging.isDebug())
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connection established");
return con;
} catch (IOException ex) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "cannot contact server %s",
server);
}
if (con != null)
con.close(implementation, ex);
throw ex;
}
}
/**
* accept a new incomming connection
*
* @param key
* the acceptable key
*/
private void acceptConnection(SelectionKey key) {
SocketChannel client = null;
TCPConnection connection = null;
// FIXME: Better exception handling!
try {
// accept connection
client = socket.accept();
connection = new TCPConnection(client,this,(InetSocketAddress)client.socket().getRemoteSocketAddress());
// and configure it to be non blocking
// IMPORTANT!
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ, connection);
//client.socket().setTcpNoDelay(true);
//numConnections.incrementAndGet();
connections.add(connection);
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connect from client at %s",
client.socket().getRemoteSocketAddress().toString());
}
implementation.onAccept(connection.getNIOConnection());
} catch (ClosedChannelException ex) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"cannot establish connection: %s", ex.toString());
}
} catch (IOException ex) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"cannot establish connection: %s", ex.toString());
}
}
}
/**
* read data from a readable connection
*
* @param key
* a readable key
*/
private void readConnection(SelectionKey key) {
final TCPConnection con = (TCPConnection) key.attachment();
final SocketChannel channel = con.getChannel();
try {
while (true) {
final ReusableBuffer readBuf = con.getReceiveBuffer();
if (readBuf == null)
return;
final int numBytesRead = channel.read(readBuf.getBuffer());
if (numBytesRead == -1) {
// connection closed
if (Logging.isInfo()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"client closed connection (EOF): %s", channel.socket()
.getRemoteSocketAddress().toString());
}
abortConnection(con,new IOException("remote end closed connection while reading data"));
return;
} else if (numBytesRead == 0) {
return;
}
implementation.onRead(con.getNIOConnection(), readBuf);
}
} catch (ClosedChannelException ex) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"connection to %s closed by remote peer", con.getChannel().socket()
.getRemoteSocketAddress().toString());
}
abortConnection(con,ex);
} catch (IOException ex) {
// simply close the connection
if (Logging.isDebug()) {
Logging.logError(Logging.LEVEL_DEBUG, this, ex);
}
abortConnection(con,ex);
}
}
/**
* write data to a writeable connection
*
* @param key
* the writable key
*/
private void writeConnection(SelectionKey key) {
final TCPConnection con = (TCPConnection) key.attachment();
final SocketChannel channel = con.getChannel();
SendRequest srq = null;
try {
while (true) {
srq = con.getSendBuffer();
if (srq == null) {
synchronized (con) {
srq = con.getSendBuffer();
if (srq == null) {
// no more responses, stop writing...
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
return;
}
}
}
// send data
final long numBytesWritten = channel.write(srq.getData().getBuffer());
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this,"wrote %d bytes to %s",numBytesWritten,channel.socket().getRemoteSocketAddress().toString());
}
if (numBytesWritten == -1) {
if (Logging.isInfo()) {
Logging.logMessage(Logging.LEVEL_INFO, Category.net, this,
"client closed connection (EOF): %s", channel.socket().getRemoteSocketAddress().toString());
}
// connection closed
abortConnection(con, new IOException("remote end closed connection while writing data"));
return;
}
if (srq.getData().hasRemaining()) {
// not enough data...
break;
}
// finished sending fragment
// clean up :-) request finished
BufferPool.free(srq.getData());
sendQueueSize.decrementAndGet();
con.nextSendBuffer();
}
} catch (ClosedChannelException ex) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,
"connection to %s closed by remote peer", con.getChannel().socket().getRemoteSocketAddress().toString());
}
abortConnection(con,ex);
} catch (IOException ex) {
// simply close the connection
if (Logging.isDebug()) {
Logging.logError(Logging.LEVEL_DEBUG, this, ex);
}
abortConnection(con,ex);
}
}
public int getSendQueueSize() {
return sendQueueSize.get();
}
void closeConnection(TCPConnection con) {
if (con.isClosed())
return;
con.setClosed();
final SocketChannel channel = con.getChannel();
// remove the connection from the selector and close socket
try {
synchronized (connections) {
connections.remove(con);
}
final SelectionKey key = channel.keyFor(selector);
if (key != null)
key.cancel();
con.close(null,null);
} catch (Exception ex) {
}
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "closing connection to %s", channel
.socket().getRemoteSocketAddress().toString());
}
}
void abortConnection(TCPConnection con, IOException exception) {
if (con.isClosed())
return;
con.setClosed();
final SocketChannel channel = con.getChannel();
// remove the connection from the selector and close socket
try {
synchronized (connections) {
connections.remove(con);
}
final SelectionKey key = channel.keyFor(selector);
if (key != null)
key.cancel();
con.close(implementation,exception);
} catch (Exception ex) {
}
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "closing connection to %s", channel
.socket().getRemoteSocketAddress().toString());
}
implementation.onClose(con.getNIOConnection());
}
int getPort() {
return this.port;
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
/**
*
* @author bjko
*/
public class TCPConnection {
private SocketChannel channel;
private Queue<SendRequest> sendQueue;
private ReusableBuffer receiveBuffer;
private final NIOConnection nioCon;
private final TCPCommunicator myServer;
private final AtomicBoolean closed;
private final InetSocketAddress endpoint;
public TCPConnection(SocketChannel channel, TCPCommunicator myServer, InetSocketAddress endpoint) {
this.channel = channel;
sendQueue = new ConcurrentLinkedQueue<SendRequest>();
nioCon = new NIOConnection(this);
this.myServer = myServer;
closed = new AtomicBoolean(false);
this.endpoint = endpoint;
}
public TCPCommunicator getServer() {
return myServer;
}
public NIOConnection getNIOConnection() {
return nioCon;
}
public SocketChannel getChannel() {
return channel;
}
public InetSocketAddress getEndpoint() {
return this.endpoint;
}
public SendRequest getSendBuffer() {
return sendQueue.peek();
}
public void nextSendBuffer() {
sendQueue.poll();
}
public void addToSendQueue(SendRequest buffer) {
sendQueue.add(buffer);
}
public boolean sendQueueIsEmpty() {
return sendQueue.isEmpty();
}
public ReusableBuffer getReceiveBuffer() {
return receiveBuffer;
}
public void setReceiveBuffer(ReusableBuffer buffer) {
receiveBuffer = buffer;
}
public boolean isClosed() {
return closed.get();
}
public void setClosed() {
closed.set(true);
}
public void close(NIOServer implementation, IOException error) {
try {
BufferPool.free(receiveBuffer);
channel.close();
} catch (IOException ex) {
//ignore
} finally {
for (SendRequest rq : sendQueue) {
BufferPool.free(rq.data);
}
if (implementation != null) {
for (SendRequest rq : sendQueue) {
if (rq.getContext() != null)
implementation.onWriteFailed(error, rq.getContext());
}
}
}
}
public static class SendRequest {
private final ReusableBuffer data;
private final Object context;
public SendRequest(ReusableBuffer data, Object context) {
this.data = data;
this.context = context;
}
/**
* @return the data
*/
public ReusableBuffer getData() {
return data;
}
/**
* @return the context
*/
public Object getContext() {
return context;
}
}
}

View File

@@ -0,0 +1,234 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm.tcp;
import org.xtreemfs.foundation.flease.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteOrder;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.xtreemfs.foundation.LifeCycleListener;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.logging.Logging;
/**
*
* @author bjko
*/
public class TCPFleaseCommunicator implements FleaseMessageSenderInterface {
private final FleaseStage stage;
private final int port;
private TCPClient comm;
private volatile boolean quit;
private final AtomicBoolean sendMode;
private final LinkedBlockingQueue<FleaseMessage> q;
private static final int MAX_UDP_SIZE = 16*1024;
private long numTx,numRx;
public static TCPFleaseCommunicator instance;
private AtomicInteger numIn, numOut;
public TCPFleaseCommunicator(FleaseConfig config, String lockfileDir,
boolean ignoreLockForTesting,
final FleaseViewChangeListenerInterface viewListener, FleaseStatusListener fsl, MasterEpochHandlerInterface meHandler) throws Exception {
stage = new FleaseStage(config, lockfileDir, this, ignoreLockForTesting, viewListener,fsl,meHandler);
port = config.getEndpoint().getPort();
q = new LinkedBlockingQueue<FleaseMessage>();
sendMode = new AtomicBoolean(false);
numTx = 0;
numRx = 0;
numIn = new AtomicInteger();
numOut = new AtomicInteger();
instance = this; //only for testing!
comm = new TCPClient(port, null, new NIOServer() {
public void onAccept(NIOConnection connection) {
ReusableBuffer hdr = BufferPool.allocate(4);
hdr.getBuffer().order(ByteOrder.LITTLE_ENDIAN);
ReusableBuffer bdy = BufferPool.allocate(2048);
bdy.getBuffer().order(ByteOrder.LITTLE_ENDIAN);
Connection c = new Connection(hdr, bdy);
connection.setContext(c);
connection.read(hdr);
}
public void onConnect(NIOConnection connection) {
onAccept(connection);
}
public void onRead(NIOConnection connection, ReusableBuffer buffer) {
Connection c = (Connection) connection.getContext();
try {
if (c.readingHdr) {
if (buffer.hasRemaining()) {
connection.read(buffer);
} else {
buffer.flip();
c.readingHdr = false;
int size = buffer.getInt();
if ((size <= 0) || (size > 2048)) {
Logging.logMessage(Logging.LEVEL_ERROR, this,"warining: invalid fragment size: %d",size);
connection.close();
return;
}
buffer.clear();
c.data.limit(size);
connection.read(c.data);
}
} else {
if (buffer.hasRemaining()) {
connection.read(buffer);
} else {
buffer.flip();
FleaseMessage m = new FleaseMessage(buffer);
m.setSender(connection.getEndpoint());
buffer.clear();
c.readingHdr = true;
connection.read(c.header);
stage.receiveMessage(m);
}
}
} catch (Exception ex) {
Logging.logError(Logging.LEVEL_ERROR, this,ex);
Logging.logMessage(Logging.LEVEL_ERROR, this,buffer.toString());
connection.close();
}
}
public void onClose(NIOConnection connection) {
Connection c = (Connection) connection.getContext();
if (c.readingHdr)
BufferPool.free(c.data);
else
BufferPool.free(c.header);
}
public void onWriteFailed(IOException exception, Object context) {
Logging.logMessage(Logging.LEVEL_ERROR, this,"write failed: "+context);
}
public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) {
Logging.logMessage(Logging.LEVEL_ERROR, this,"could not connect to: "+endpoint);
}
});
/*Timer t = new Timer(true);
t.scheduleAtFixedRate(new TimerTask() {
long maxQsize = 0;
long sum = 0;
long numSamples = 0;
int cnt = 0;
@Override
public void run() {
long size = comm.getSendQueueSize();
sum = sum+size;
numSamples++;
if (size > maxQsize)
maxQsize = size;
cnt++;
if (cnt == 10) {
System.out.println("avg: "+(sum/numSamples)+" max: "+maxQsize);
cnt = 0;
}
}
}, 10, 1000);*/
}
public FleaseStage getStage() {
return stage;
}
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
FleaseMessage m = message.clone();
m.setSender(recipient);
send(m);
if (FleaseStage.COLLECT_STATISTICS)
numOut.incrementAndGet();
}
/**
* sends a UDPRequest.
*
* @attention Overwrites the first byte of rq.data with the message type.
*/
public void send(FleaseMessage rq) {
if (FleaseStage.COLLECT_STATISTICS)
numIn.incrementAndGet();
final int size = rq.getSize();
ReusableBuffer data = BufferPool.allocate(size+4);
data.getBuffer().order(ByteOrder.LITTLE_ENDIAN);
data.putInt(size);
rq.serialize(data);
data.getBuffer().order(ByteOrder.BIG_ENDIAN);
data.flip();
if (data.remaining() != size+4)
throw new IllegalStateException("data is wrong: "+data);
comm.write(rq.getSender(), data, null);
}
public void start() throws Exception {
comm.start();
comm.waitForStartup();
stage.start();
stage.waitForStartup();
}
public void shutdown() throws Exception {
stage.shutdown();
stage.waitForShutdown();
comm.shutdown();
comm.waitForShutdown();
}
public void setLifeCycleListener(LifeCycleListener l) {
comm.setLifeCycleListener(l);
stage.setLifeCycleListener(l);
}
public int getNumIn() {
return numIn.getAndSet(0);
}
public int getNumOut() {
return numOut.getAndSet(0);
}
private static class Connection {
public ReusableBuffer header;
public ReusableBuffer data;
public boolean readingHdr;
public Connection(ReusableBuffer header, ReusableBuffer data) {
this.header = header;
this.data = data;
readingHdr = true;
}
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (c) 2012 by Bjoern Kolbeck.
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.proposer;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Stores a single action for traces.
* @author bjko
*/
public class CellAction {
private final ActionName actionName;
private final String message;
public static enum ActionName {
PROPOSER_SET_VIEWID,
PROPOSER_CELL_OPENED,
PROPOSER_CELL_CLOSED,
PROPOSER_ACQUIRE_LEASE,
PROPOSER_RETURNED_LOCAL_LEASE,
PROPOSER_START_RENEW,
PROPOSER_RENEW_CANCELLED,
PROPOSER_RENEW_FAILED_NO_LEASE,
PROPOSER_RENEW_FAILED_LEASE_TO,
PROPOSER_RENEW_FAILED_LEASE_NOT_ENOUGH_TIME,
PROPOSER_RENEW_FAILED_NOT_OWNER,
PROPOSER_HANDOVER_LEASE,
PROPOSER_RESTART_EVENT,
PROPOSER_RENEW_EVENT,
PROPOSER_INTERNAL_ERROR_CELL_RESET,
PROPOSER_SET_BALLOT_NO,
PROPOSER_REQUEST_MASTER_EPOCH,
PROPOSER_WAIT_FOR_ACK,
PROPOSER_PREPARE_START,
PROPOSER_PREPARE_PROCESS_RESPONSE,
PROPOSER_PREPARE_TIMEOUT,
PROPOSER_VIEW_OUTDATED,
PROPOSER_PREPARE_OVERRULED,
PROPOSER_PREPARE_SUCCESS,
PROPOSER_PREPARE_EMPTY,
PROPOSER_PREPARE_PRIOR_VALUE,
PROPOSER_PREPARE_IMPLICIT_RENEW,
PROPOSER_PREPARE_MAX_MASTER_EPOCH,
PROPOSER_ACCEPT_START,
PROPOSER_ACCEPT_PROCESS_RESPONSE,
PROPOSER_ACCEPT_TIMEOUT,
PROPOSER_ACCEPT_OVERRULED,
PROPOSER_LEARN_START,
PROPOSER_LEARN_TIMED_OUT,
PROPOSER_SCHEDULED_RENEW,
PROPOSER_LEARN_LEASE_IN_GRACE_PERIOD,
PROPOSER_CANCELLED,
PROPOSER_CANCEL_LEASE_FAILED,
PROPOSER_CANCEL_SCHEDULE_RESTART,
PROPOSER_RECEIVED_OUT_OF_SYNC_MSG,
PROPOSER_RENEW_LEASE,
PROPOSER_RENEW_FAILED_NO_LOCAL_LEASE_INFO,
PROPOSER_SCHEDULED_RESTART,
PROPOSER_SCHEDULED_TIMEOUT,
PROPOSER_PREPARE_FAILED,
PROPOSER_PREPARE_LEASE_TO,
PROPOSER_ACCEPT_FAILED,
PROPOSER_ACCEPT_SUCCESS,
}
public static class CellActionList implements Iterable<CellAction> {
public static final int MAX_ACTIONS_IN_LIST = 50;
List<CellAction> actions;
public CellActionList() {
actions = new LinkedList<CellAction>();
}
public void addAction(ActionName actionName) {
addAction(actionName, null);
}
public void addAction(ActionName actionName, String message) {
actions.add(new CellAction(actionName, message));
if (actions.size() > MAX_ACTIONS_IN_LIST) {
actions.remove(0);
}
}
@Override
public Iterator<CellAction> iterator() {
return actions.iterator();
}
@Override
public String toString() {
StringBuilder text = new StringBuilder();
text.append("actions:[");
Iterator<CellAction> iter = iterator();
while (iter.hasNext()) {
CellAction action = iter.next();
text.append(action);
if (iter.hasNext()) {
text.append(", ");
}
}
text.append("]");
return text.toString();
}
}
public CellAction(ActionName actionName) {
this.actionName = actionName;
this.message = null;
}
public CellAction(ActionName actionName, String message) {
this.actionName = actionName;
this.message = message;
}
public String toString() {
return actionName + (message != null
? " (" + message +")"
: "");
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.proposer;
/**
*
* @author bjko
*/
public class FleaseException extends Exception {
private String fleaseCellDebugString = null;
public FleaseException(String message) {
super(message);
}
public FleaseException(String message, Throwable cause) {
super(message, cause);
}
public void addFleaseCellDebugString(String fleaseCellDebugString) {
this.fleaseCellDebugString = fleaseCellDebugString;
}
public String getFleaseCellDebugString() {
return fleaseCellDebugString;
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.proposer;
import org.xtreemfs.foundation.buffer.ASCIIString;
/**
*
* @author bjko
*/
public interface FleaseListener {
public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber);
public void proposalFailed(ASCIIString cellId, Throwable cause);
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.proposer;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
/**
*
* @author bjko
*/
public interface FleaseLocalQueueInterface {
public void enqueueMessage(FleaseMessage message);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,331 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.proposer;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.Flease;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.comm.ProposalNumber;
import org.xtreemfs.foundation.flease.proposer.CellAction.ActionName;
import org.xtreemfs.foundation.flease.proposer.CellAction.CellActionList;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
*
* @author bjko
*/
public class FleaseProposerCell {
/**
* @return the responses
*/
public List<FleaseMessage> getResponses() {
return responses;
}
/**
* @return the messageSent
*/
public FleaseMessage getMessageSent() {
return messageSent;
}
/**
* @param messageSent the messageSent to set
*/
public void setMessageSent(FleaseMessage messageSent) {
this.messageSent = messageSent;
}
/**
* @return the lastPrepateTimestamp_ms
*/
public long getLastPrepareTimestamp_ms() {
return lastPrepateTimestamp_ms;
}
public void setViewId(int viewId) {
this.viewId = viewId;
}
public int getViewId() {
return this.viewId;
}
public boolean isHandoverInProgress() {
return handoverTo != null;
}
/**
* @return the prevLease
*/
public Flease getPrevLease() {
return prevLease;
}
/**
* @param prevLease the prevLease to set
*/
public void setPrevLease(Flease prevLease) {
this.prevLease = prevLease;
}
/**
* @return the markedClose
*/
public boolean isMarkedClose() {
return markedClose;
}
/**
* @param markedClose the markedClose to set
*/
public void setMarkedClose(boolean markedClose) {
this.markedClose = markedClose;
}
/**
* @return the requestMasteEpoch
*/
public boolean isRequestMasteEpoch() {
return requestMasteEpoch;
}
/**
* @param requestMasteEpoch the requestMasteEpoch to set
*/
public void setRequestMasteEpoch(boolean requestMasteEpoch) {
this.requestMasteEpoch = requestMasteEpoch;
}
/**
* @return the masterEpochNumber
*/
public long getMasterEpochNumber() {
return masterEpochNumber;
}
/**
* @param masterEpochNumber the masterEpochNumber to set
*/
public void setMasterEpochNumber(long masterEpochNumber) {
this.masterEpochNumber = masterEpochNumber;
}
public static enum State {
IDLE,
WAIT_FOR_PREP_ACK,
WAIT_FOR_ACCEPT_ACK,
};
private final ASCIIString cellId;
private ProposalNumber ballotNo;
private List<InetSocketAddress> acceptors;
private final List<FleaseListener> listeners;
private final List<FleaseMessage> responses;
private State cellState;
private int numFailures;
private final int majority;
private long lastPrepateTimestamp_ms;
private int viewId;
private Flease prevLease;
private boolean markedClose;
private ASCIIString handoverTo;
private boolean requestMasteEpoch;
private long masterEpochNumber;
private final CellActionList actions;
/**
* the value to use for prepare, accept and learn
* might be != than the local host, if the proposer
* must use a previously accepted value
*/
private FleaseMessage messageSent;
FleaseProposerCell(ASCIIString cellId, List<InetSocketAddress> acceptors, long senderId) {
this.actions = new CellActionList();
this.cellId = cellId;
this.acceptors = acceptors;
this.responses = new ArrayList(acceptors.size()+1);
this.listeners = new ArrayList(5);
this.ballotNo = new ProposalNumber(TimeSync.getGlobalTime(),senderId);
this.majority = (int) Math.floor((acceptors.size()+1.0)/ 2.0) + 1;
this.prevLease = Flease.EMPTY_LEASE;
this.markedClose = false;
this.handoverTo = null;
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"opened new cell id %s with majority = %d ",cellId,majority);
}
}
public void addAction(ActionName actionName) {
actions.addAction(actionName);
}
public void addAction(ActionName actionName, String message) {
actions.addAction(actionName, message);
}
public boolean majorityAvail() {
return responses.size() >= this.majority;
}
/**
* @return the cellId
*/
public ASCIIString getCellId() {
return cellId;
}
/**
* @return the ballotNo
*/
public ProposalNumber getBallotNo() {
return ballotNo;
}
/**
* @param ballotNo the ballotNo to set
*/
public void setBallotNo(ProposalNumber ballotNo) {
this.ballotNo = ballotNo;
}
/**
* @return the acceptors
*/
public List<InetSocketAddress> getAcceptors() {
return acceptors;
}
/**
* @param acceptors the acceptors to set
*/
public void setAcceptors(List<InetSocketAddress> acceptors) {
this.acceptors = acceptors;
}
/**
* @return the cellState
*/
public State getCellState() {
return cellState;
}
/**
* @param cellState the cellState to set
*/
public void setCellState(State cellState) {
this.cellState = cellState;
}
/**
* @return the listeners
*/
public List<FleaseListener> getListeners() {
return listeners;
}
public int getNumAcceptors() {
return acceptors.size();
}
/**
* @return the numFailures
*/
public int getNumFailures() {
return numFailures;
}
/**
* @param numFailures the numFailures to set
*/
public void setNumFailures(int numFailures) {
this.numFailures = numFailures;
}
public void touch() {
this.lastPrepateTimestamp_ms = TimeSync.getLocalSystemTime();
}
/**
* @return the handoverTo
*/
public ASCIIString getHandoverTo() {
return handoverTo;
}
/**
* @param handoverTo the handoverTo to set
*/
public void setHandoverTo(ASCIIString handoverTo) {
this.handoverTo = handoverTo;
}
@Override
public String toString() {
StringBuilder text = new StringBuilder();
text.append(getClass().getSimpleName());
text.append(":{");
text.append(" cellId:");
text.append(cellId);
text.append(" ballotNo:");
text.append(ballotNo);
text.append(" numAcceptors:");
text.append(acceptors != null ? acceptors.size() : "null");
text.append(" numResponses:");
text.append(responses != null ? responses.size() : "null");
text.append(" cellState:");
text.append(cellState);
text.append(" numFail:");
text.append(numFailures);
text.append(" majority:");
text.append(majority);
text.append(" lastPTSP:");
text.append(lastPrepateTimestamp_ms);
text.append(" viewId:");
text.append(viewId);
text.append(" prevL:");
text.append(prevLease != null ? prevLease : "none");
text.append(" markedClose:");
text.append(markedClose);
text.append(" rqME:");
text.append(requestMasteEpoch);
text.append(" msgSent:");
text.append(messageSent);
text.append(" responses:");
for (FleaseMessage r : responses) {
text.append(r);
text.append(",");
}
text.append(" actions:");
text.append(actions);
text.append("}");
return text.toString();
}
}

View File

@@ -0,0 +1,311 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.sim;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import org.xtreemfs.foundation.LifeCycleThread;
import org.xtreemfs.foundation.flease.FleaseStage;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.logging.Logging;
/**
* A tool to simulate package loss, temporary host disconnects and message delay.
* @author bjko
*/
public class Communicator extends LifeCycleThread {
/**
* the connected UDPSimSockets
*/
protected final Map<Integer,FleaseStage> ports;
/**
* sockets which are currently blocked (i.e. simulated network outage)
*/
protected final Map<Integer,Integer> blockedPorts;
/**
* the packet loss in percent (0..100)
*/
private int pkgLossPct;
/**
* if true the thread will quit operation
*/
private boolean quit;
/**
* debug output is generated if set to true
*/
private boolean debug;
/**
* queue with packets to be delivered to sockets
*/
private final LinkedBlockingQueue<Packet> sendQ;
/**
* singleton
*/
private static volatile Communicator theInstance;
/**
* thread for delayed delivery and blocking ports
*/
private DelayedDelivery dd;
private int minDelay;
private int maxDelay;
/**
* percent of packets to be delayed
*/
private int pctDelay;
/**
* if set to true, ports are blocked unsymmetric (i.e. receive but cannot send)
*/
private boolean halfLink;
/**
* Creates a new instance of UDPSim
* @param pkgLossPct packet loss in percent
* @param minDelay minimum delay of a delayed packet
* @param maxDelay maximum delay of a delayed packet
* @param pctDelay percentage of packets to be delayed
* @param halfLink if set to true, ports are blocked unsymmetric (i.e. receive but cannot send)
* @param pHostUnavail probability (0..1) that a host becomes unavailable
* @param pHostRecovery probability that a host is recovered. This value is multiplied by the
* number of rounds that the host is already unavailable.
* @param debug if set to true extensive debug output is generated
*/
public Communicator(int pkgLossPct, int minDelay, int maxDelay, int pctDelay,
boolean halfLink, double pHostUnavail, double pHostRecovery,
boolean debug) {
super("UDP-Sim");
this.ports = new ConcurrentHashMap();
this.blockedPorts = new ConcurrentHashMap();
this.pkgLossPct = pkgLossPct;
this.quit = false;
this.debug = debug;
this.sendQ = new LinkedBlockingQueue();
this.dd = new DelayedDelivery(sendQ,blockedPorts,ports,
pHostUnavail,pHostRecovery,
debug);
dd.start();
this.minDelay = minDelay;
this.maxDelay = maxDelay;
this.pctDelay = pctDelay;
this.halfLink = halfLink;
theInstance = this;
}
/**
* opens a port and delivers messages into the queue
* @param port port number to open
* @param q the queue to receive messages
* @return true if the port was opened succesfully, false if the port is already in use
*/
public boolean openPort(int port, FleaseStage stage) {
if (ports.get(port) != null)
return false;
ports.put(port,stage);
return true;
}
/**
* Opens a free port
* @param q the queue to receive messages
* @return treu if successful, false if there is no free port available
*/
public int openPort(FleaseStage stage) {
int tries = 0;
while (tries < 5) {
int rport = (int)(Math.random()*65000.0)+1;
if (ports.get(rport) == null) {
ports.put(rport,stage);
return rport;
}
tries++;
}
return -1;
}
/**
* closes the port
* @param port port number to close
*/
public void closePort(int port) {
ports.remove(port);
}
/**
* sends a datagram packet from
* @param port sending port number
* @param dp packet to send
*/
public synchronized void send(int port, FleaseMessage msg) {
Packet p = new Packet(msg,port);
sendQ.add(p);
}
/**
* main loop
*/
public void run() {
try {
InetAddress ia = InetAddress.getLocalHost();
notifyStarted();
while (!quit) {
try {
Packet p = sendQ.take();
FleaseStage rec = ports.get(p.recipientPort);
if (rec == null)
continue;
if (blockedPorts.containsKey(p.msg.getSender().getPort())) {
if (debug)
Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg dropped, port blocked "+p.msg.getSender().getPort());
continue;
}
if (blockedPorts.containsKey(p.recipientPort)) {
if (debug)
Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg dropped, port blocked "+p.recipientPort);
continue;
}
if (!dropPacket() || p.requeued) {
int delay = delayPacket();
if ((delay > 0) && !p.requeued) {
if (debug)
Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg delayed "+delay+"ms "+p.recipientPort+" -> "+p.msg.getSender().getPort());
dd.add(p,delay);
} else {
//p.msg.setSender(new InetSocketAddress(ia, p.recipientPort));
try {
rec.receiveMessage(p.msg);
} catch (IllegalStateException e) {
//just drop it
}
}
} else {
if (debug)
Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg lost "+p.recipientPort+" -> "+p.msg.getSender().getPort());
}
} catch (InterruptedException ex) {
Logging.logError(Logging.LEVEL_ERROR,this,ex);
}
}
} catch (UnknownHostException ex) {
Logging.logError(Logging.LEVEL_ERROR,this,ex);
}
notifyStopped();
}
/**
* decides if a message should be dropped.
* @return true, if the packet is to be dropped
*/
private boolean dropPacket() {
int rv = (int)(Math.random()*100.0);
return (rv < this.pkgLossPct);
}
/**
* singleton
* @return null, if not initialized, the instance otherwise
*/
public static Communicator getInstance() {
return theInstance;
}
/**
* kills the thread and the delayed delivery thread
*/
public void shutdown() {
try {
this.quit = true;
this.interrupt();
dd.shutdown();
dd.waitForShutdown();
waitForShutdown();
} catch (Exception exc) {
Logging.logError(Logging.LEVEL_ERROR, this, exc);
}
}
/**
* decides if and how long a packet is delayed
* @return delay in ms
*/
private int delayPacket() {
if (pctDelay == 0)
return 0;
int rv = (int)(Math.random()*100.0);
if (rv < this.pctDelay) {
return (int)(Math.random()*((double)maxDelay-minDelay))+minDelay;
} else {
return 0;
}
}
/**
* Packet information
*/
protected static class Packet {
/**
* the datagram that is being sent
*/
public FleaseMessage msg;
/**
* originating prot number
*/
public int recipientPort;
/**
* set to true if it was requeued after delay (i.e. must not be dropped, delayed...)
*/
public boolean requeued;
/**
* creates a new packet
* @param dp datagram packet
* @param port originating port
*/
public Packet(FleaseMessage msg, int port) {
this.msg = msg;
this.recipientPort = port;
this.requeued = false;
}
}
}

View File

@@ -0,0 +1,224 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.sim;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import org.xtreemfs.foundation.LifeCycleThread;
import org.xtreemfs.foundation.flease.FleaseStage;
import org.xtreemfs.foundation.logging.Logging;
/**
* Thread to deliver delayed packets and to set availability status of hosts.
* @author bjko
*/
public class DelayedDelivery extends LifeCycleThread {
/**
* queued packets for delayed delivery
*/
private final LinkedList<DelayPacket> packets;
/**
* sending queue
*/
private final LinkedBlockingQueue<Communicator.Packet> targetQ;
/**
* minimum delay in ms
*/
private int minDelay;
/**
* maximum delay in ms
*/
private int maxDelay;
/**
* if set to true the thread shuts down
*/
private boolean quit;
/**
* time to wait between two invocations in ms
*/
private static final int WAIT_TIME = 50;
/**
* list of blocked ports (unavailable hosts)
*/
private final Map<Integer,Integer> blockedPorts;
/**
* all ports
*/
private final Map<Integer,FleaseStage> ports;
/**
* probability of unavailable host
*/
private double pHostUnavail;
/**
* probability of host recovery
*/
private double pHostRecovery;
/**
* number of rounds (i.e. WAIT_TIME) to wait between checks for host availability
*/
private final static int HOSTWAIT_MULTIPLIER = 10;
/**
* if set to true debug output is generated
*/
private boolean debug;
/**
* Creates a new instance of UDPDelayedDelivery
* @param targetQ queue to use for delivering delayed packets
* @param blockedPorts list of blocked ports (unavail hosts)
* @param ports list of all hosts
* @param pHostUnavail probability of unavailable host
* @param pHostRecovery probability of host recovery
* @param debug if set to true debug output is generated
*/
public DelayedDelivery(LinkedBlockingQueue<Communicator.Packet> targetQ,
Map<Integer,Integer> blockedPorts,
Map<Integer,FleaseStage> ports,
double pHostUnavail, double pHostRecovery, boolean debug) {
super("UDP-Delivery");
this.packets = new LinkedList();
this.targetQ = targetQ;
/*this.minDelay = minDelay;
this.maxDelay = maxDelay;*/
this.pHostUnavail = pHostUnavail;
this.pHostRecovery = pHostRecovery;
this.blockedPorts = blockedPorts;
this.ports = ports;
this.quit = false;
this.debug = debug;
}
/**
* adds a packet for delyed delivery
* @param p packet to send
* @param delay delay in ms
*/
public void add(Communicator.Packet p, int delay) {
synchronized (packets) {
DelayPacket dp = new DelayPacket();
dp.packet = p;
dp.waited = 0;
dp.delay = delay;
packets.add(dp);
}
}
/**
* main loop
*/
public void run() {
notifyStarted();
int hostwait = 0;
while (!quit) {
synchronized (packets) {
Iterator<DelayPacket> iter = packets.iterator();
while (iter.hasNext()) {
DelayPacket dp = iter.next();
try {
dp.waited += WAIT_TIME;
if (dp.waited >= dp.delay) {
dp.packet.requeued = true;
iter.remove();
targetQ.add(dp.packet);
}
} catch (IllegalStateException ex) {
}
}
}
//check only every 10*WAIT_TIME
hostwait++;
if (hostwait == HOSTWAIT_MULTIPLIER) {
//check if hosts should become available again...
Iterator<Integer> iter = blockedPorts.keySet().iterator();
while (iter.hasNext()) {
int portNo = iter.next();
int round = blockedPorts.get(portNo);
if (Math.random() < this.pHostRecovery*round) {
iter.remove();
if (debug)
Logging.logMessage(Logging.LEVEL_DEBUG,this,"unblocked "+portNo);
} else {
blockedPorts.put(portNo,round+1);
}
}
//make hosts unavailable
if (blockedPorts.size() < ports.size()) {
if (Math.random() < this.pHostUnavail) {
//get a random host to make unavailable
Integer[] keys = ports.keySet().toArray(new Integer[0]);
int rand = (int)(Math.random()*(double)(keys.length));
blockedPorts.put(keys[rand],1);
if (debug)
Logging.logMessage(Logging.LEVEL_DEBUG,this,"blocked "+keys[rand]);
}
}
hostwait = 0;
}
synchronized (this) {
try {
this.wait(WAIT_TIME);
} catch (InterruptedException ex) {
}
}
}
notifyStopped();
}
/**
* shuts down the thread
*/
public void shutdown() {
this.quit = true;
this.interrupt();
}
/**
* information on packet to be delayed
*/
protected static class DelayPacket {
/**
* packet to send
*/
Communicator.Packet packet;
int delay;
/**
* time already waited
*/
int waited;
}
}

View File

@@ -0,0 +1,231 @@
///*
// * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
// *
// * Licensed under the BSD License, see LICENSE file for details.
// *
// */
//
//package org.xtreemfs.foundation.flease.sim;
//
//import java.net.InetSocketAddress;
//import java.util.ArrayList;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.Semaphore;
//import java.util.concurrent.TimeUnit;
//import org.xtreemfs.common.TimeSync;
//import org.xtreemfs.common.buffer.ASCIIString;
//import org.xtreemfs.common.logging.Logging;
//import org.xtreemfs.common.logging.Logging.Category;
//import org.xtreemfs.foundation.LifeCycleListener;
//import org.xtreemfs.foundation.flease.FleaseConfig;
//import org.xtreemfs.foundation.flease.FleaseMessageSenderInterface;
//import org.xtreemfs.foundation.flease.FleaseStage;
//import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface;
//import org.xtreemfs.foundation.flease.comm.FleaseMessage;
//import org.xtreemfs.foundation.flease.proposer.FleaseListener;
//
///**
// * Simulator for testing
// * @author bjko
// */
//public class FleaseMultiSim {
//
// //private void
//
// /**
// * @param args the command line arguments
// */
// public static void main(String[] args) {
// try {
//
// final boolean DEBUG_COMM_MSGS = false;
//
// final int dmax = 500;
// final int leaseTimeout = 10000;
//
// final int numHosts = 10;
// final int numConcurrentProposers = 10;
// final FleaseStage[] stages = new FleaseStage[numHosts];
//
// Logging.start(Logging.LEVEL_DEBUG, Category.all);
// TimeSync.initializeLocal(10000, 50);
//
// final Communicator com = new Communicator(10, 10, 2000, 5, true, 0.05, 0.05, DEBUG_COMM_MSGS);
// com.start();
//
// List<InetSocketAddress> allPorts = new ArrayList(numHosts);
// List<InetSocketAddress>[] acceptors = new List[numHosts];
//
// for (int i = 0; i < numHosts; i++) {
// final int portNo = 1024+i;
// FleaseConfig cfg = new FleaseConfig(leaseTimeout, dmax, 500, new InetSocketAddress(portNo), "localhost:"+(1024+i),5);
// stages[i] = new FleaseStage(cfg, "/tmp/xtreemfs-test", new FleaseMessageSenderInterface() {
//
// public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
// assert(message != null);
// if (DEBUG_COMM_MSGS)
// Logging.logMessage(Logging.LEVEL_DEBUG, this,"received message for delivery to port %d: %s",recipient.getPort(),message.toString());
// message.setSender(new InetSocketAddress("localhost", portNo));
// com.send(recipient.getPort(), message);
// }
// }, true, new FleaseViewChangeListenerInterface() {
//
// public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
// //ignore
// }
// },null);
// stages[i].setLifeCycleListener(new LifeCycleListener() {
//
// public void startupPerformed() {
// }
//
// public void shutdownPerformed() {
// }
//
// public void crashPerformed(Throwable cause) {
// cause.printStackTrace();
// System.exit(100);
// }
// });
// stages[i].start();
// allPorts.add(new InetSocketAddress("localhost", 1024+i));
// com.openPort(1024+i, stages[i]);
// }
//
// for (int i = 0; i < numHosts; i++) {
// final int portNo = 1024+i;
// acceptors[i] = new ArrayList(numHosts-1);
// for (InetSocketAddress ia : allPorts) {
// if (ia.getPort() != portNo)
// acceptors[i].add(ia);
// }
// stages[i].openCell(new ASCIIString("testcell"), acceptors[i],true);
// }
//
// //do something
//
// do {
// final List<LInfo> results = new ArrayList(numHosts);
// final Semaphore s = new Semaphore(0);
//
//
// final List<Integer> hostNumbers = new ArrayList(numHosts);
// for (int i = 0; i < numHosts; i++)
// hostNumbers.add(i);
//
// while (hostNumbers.size()+numConcurrentProposers > numHosts) {
// final int tmp = (int)(Math.random()*hostNumbers.size());
// final int host = hostNumbers.remove((int)tmp);
// stages[host].getLease(new ASCIIString("testcell"), new FleaseListener() {
//
// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) {
// final ASCIIString id = stages[host].getIdentity();
// synchronized (results) {
// LInfo i = new LInfo();
// i.host = id;
// i.owner = leaseHolder;
// i.to = leaseTimeout_ms;
// results.add(i);
// }
// s.release();
// System.out.println("host: "+id+". lease result: "+leaseHolder+"/"+leaseTimeout_ms);
// }
//
// public void proposalFailed(ASCIIString cellId, Throwable cause) {
// final ASCIIString id = stages[host].getIdentity();
// System.out.println("host: "+id+". lease failed: "+cause);
// s.release();
// }
// });
// }
// System.out.println("all started");
//
// if (!s.tryAcquire(numConcurrentProposers, 30000, TimeUnit.MILLISECONDS)) {
// throw new RuntimeException("timed out waiting for semaphore");
// }
//
// System.out.println("all results available");
// final long now = TimeSync.getGlobalTime();
//
// //first: remove all leases which are timed out
// Iterator<LInfo> iter = results.iterator();
// while (iter.hasNext()) {
// LInfo i = iter.next();
// if (i.to+dmax < now) {
// iter.remove();
// }
// }
//
// //now check all the values
// ASCIIString owner = null;
// LInfo other = null;
// boolean violated = false;
// for (LInfo i : results) {
// if (owner == null) {
// owner = i.owner;
// other = i;
// } else {
// if (!owner.equals(i.owner)) {
// com.shutdown();
// Map<Thread,StackTraceElement[]> traces = Thread.getAllStackTraces();
// System.out.println("INVARIANT VIOLATED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// System.out.println("\n\n");
// System.out.println(i.host+" has : "+i.owner+"/"+i.to);
// System.out.println(other.host+" has : "+other.owner+"/"+other.to);
//
// for (int j = 0; j < numHosts; j++) {
// System.out.println(stages[j]._dump_acceptor_state(new ASCIIString("testcell")));
// }
//
// System.out.println("");
// for (Thread t : traces.keySet()) {
// System.out.println("Thread: "+t.getName());
// final StackTraceElement[] e = traces.get(t);
// for (StackTraceElement elem : e) {
// System.out.println(elem.toString());
// }
// }
// System.exit(2);
// }
// }
// }
//
//
// //make sure that cells also time out some times (requires a wait > 2*lease_timeout)
// final int waitTime = (int)(Math.random()*(leaseTimeout*2+2000+dmax));
// System.out.println("waiting for "+waitTime+"ms");
// Thread.sleep(waitTime);
// } while (true);
// /*
// for (int i = 0; i < numHosts; i++) {
// stages[i].shutdown();
// }
// com.shutdown();
// */
//
// } catch (Exception ex) {
// ex.printStackTrace();
// Map<Thread,StackTraceElement[]> traces = Thread.getAllStackTraces();
// System.out.println("");
// for (Thread t : traces.keySet()) {
// System.out.println("Thread: "+t.getName());
// final StackTraceElement[] e = traces.get(t);
// for (StackTraceElement elem : e) {
// System.out.println(elem.toString());
// }
// }
// System.exit(1);
// }
//
// }
//
// public static final class LInfo {
// ASCIIString host;
// ASCIIString owner;
// long to;
//
// }
//
//}

View File

@@ -0,0 +1,223 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.sim;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.xtreemfs.foundation.LifeCycleListener;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.Flease;
import org.xtreemfs.foundation.flease.FleaseConfig;
import org.xtreemfs.foundation.flease.FleaseMessageSenderInterface;
import org.xtreemfs.foundation.flease.FleaseStage;
import org.xtreemfs.foundation.flease.FleaseStatusListener;
import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface;
import org.xtreemfs.foundation.flease.MasterEpochHandlerInterface;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
* Simulator for testing
* @author bjko
*/
public class FleaseSim {
//private void
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
final boolean DEBUG_COMM_MSGS = false;
final int dmax = 500;
final int leaseTimeout = 5000;
final int numHosts = 10;
final FleaseStage[] stages = new FleaseStage[numHosts];
final boolean useME = true;
Logging.start(Logging.LEVEL_DEBUG, Category.all);
TimeSync.initializeLocal(50);
final Communicator com = new Communicator(10, 100, 30000, 5, true, 0.2, 0.05, DEBUG_COMM_MSGS);
com.start();
List<InetSocketAddress> allPorts = new ArrayList(numHosts);
List<InetSocketAddress>[] acceptors = new List[numHosts];
MasterEpochHandlerInterface[] meHandlers = new MasterEpochHandlerInterface[numHosts];
final AtomicReference<Flease>[] leaseStates = new AtomicReference[numHosts];
for (int i = 0; i < numHosts; i++) {
final int portNo = 1024+i;
final int myI = i;
FleaseConfig cfg = new FleaseConfig(leaseTimeout, dmax, 500, new InetSocketAddress(portNo), "localhost:"+(1024+i),5, true, 0, true);
leaseStates[i] = new AtomicReference<Flease>(Flease.EMPTY_LEASE);
if (useME) {
meHandlers[i] = new MasterEpochHandlerInterface() {
long me = 0;
public long getMasterEpoch() {
return me;
}
@Override
public void sendMasterEpoch(FleaseMessage response, Continuation callback) {
response.setMasterEpochNumber(me);
callback.processingFinished();
}
@Override
public void storeMasterEpoch(FleaseMessage request, Continuation callback) {
me = request.getMasterEpochNumber();
callback.processingFinished();
}
};
}
stages[i] = new FleaseStage(cfg, "/tmp/xtreemfs-test", new FleaseMessageSenderInterface() {
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
assert(message != null);
if (DEBUG_COMM_MSGS)
Logging.logMessage(Logging.LEVEL_DEBUG, this,"received message for delivery to port %d: %s",recipient.getPort(),message.toString());
message.setSender(new InetSocketAddress("localhost", portNo));
com.send(recipient.getPort(), message);
}
}, true, new FleaseViewChangeListenerInterface() {
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
public void statusChanged(ASCIIString cellId, Flease lease) {
synchronized (leaseStates) {
leaseStates[myI].set(lease);
}
System.out.println("state change for "+portNo+": "+lease.getLeaseHolder()+"/"+lease.getLeaseTimeout_ms());
}
public void leaseFailed(ASCIIString cellId, FleaseException error) {
System.out.println("lease failed: "+error);
synchronized (leaseStates) {
leaseStates[myI].set(Flease.EMPTY_LEASE);
}
//restart my cell
}
},meHandlers[i]);
stages[i].setLifeCycleListener(new LifeCycleListener() {
public void startupPerformed() {
}
public void shutdownPerformed() {
}
public void crashPerformed(Throwable cause) {
cause.printStackTrace();
System.exit(100);
}
});
stages[i].start();
allPorts.add(new InetSocketAddress("localhost", 1024+i));
com.openPort(1024+i, stages[i]);
}
for (int i = 0; i < numHosts; i++) {
final int portNo = 1024+i;
acceptors[i] = new ArrayList(numHosts-1);
for (InetSocketAddress ia : allPorts) {
if (ia.getPort() != portNo)
acceptors[i].add(ia);
}
stages[i].openCell(new ASCIIString("testcell"), acceptors[i],false);
}
//do something
do {
final AtomicBoolean sync = new AtomicBoolean();
final AtomicReference<ASCIIString> ref = new AtomicReference();
Thread.sleep(100);
System.out.print("checking local states: ");
ASCIIString leaseHolder = null;
int leaseInstanceId = 0;
synchronized (leaseStates) {
for (int i = 0; i < numHosts; i++) {
if (!leaseStates[i].get().isEmptyLease()) {
if (leaseHolder == null) {
leaseHolder = leaseStates[i].get().getLeaseHolder();
} else {
if (!leaseHolder.equals(leaseStates[i].get().getLeaseHolder())) {
com.shutdown();
System.out.println("INVARIANT VIOLATED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
System.out.println("\n\n");
System.out.println("got lease for: "+leaseHolder);
System.out.println("but host "+i+" learned "+leaseStates[i].get().getLeaseHolder());
for (int j = 0; j < numHosts; j++) {
System.out.println(stages[j]._dump_acceptor_state(new ASCIIString("testcell")));
System.out.println("signalled result: "+leaseStates[j].get());
System.out.println(" valid: "+leaseStates[j].get().isValid());
}
System.exit(2);
} else {
System.out.print("+");
}
}
} else {
System.out.print("o");
}
}
}
System.out.println("");
final int host = (int)(Math.random()*numHosts);
stages[host].closeCell(new ASCIIString("testcell"), false);
//make sure that cells also time out some times (requires a wait > 2*lease_timeout)
final int waitTime = (int)(Math.random()*(leaseTimeout*2+1000));
System.out.println("waiting for "+waitTime+"ms");
Thread.sleep(waitTime);
stages[host].openCell(new ASCIIString("testcell"), acceptors[host],false);
} while (true);
/*
for (int i = 0; i < numHosts; i++) {
stages[i].shutdown();
}
com.shutdown();
*/
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}

View File

@@ -0,0 +1,231 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
import org.xtreemfs.foundation.util.FSUtils;
/**
*
* @author bjko
*/
public class FleaseStageTest {
private static FleaseConfig cfg;
private static File testDir;
@BeforeClass
public static void setUpClass() {
Logging.start(Logging.LEVEL_WARN, Category.all);
TimeSync.initializeLocal(50);
cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5);
testDir = new File("/tmp/xtreemfs-test/");
}
@Before
public void setUp() throws Exception {
FSUtils.delTree(testDir);
testDir.mkdirs();
}
@After
public void tearDown() throws Exception {
}
/**
* Test of createTimer method, of class FleaseStage.
*/
@Test
public void testOpenAndGetLease() throws Exception {
final ASCIIString CELL_ID = new ASCIIString("testcell");
final AtomicReference<Flease> result = new AtomicReference();
FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {
@Override
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
//ignore me
}
}, true, new FleaseViewChangeListenerInterface() {
@Override
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
// System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder());
synchronized (result) {
result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber()));
result.notify();
}
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
fail(error.toString());
}
}, null);
FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
msg.setCellId(CELL_ID);
fs.start();
fs.waitForStartup();
fs.openCell(CELL_ID, new ArrayList(),false);
synchronized(result) {
if (result.get() == null)
result.wait(1000);
if (result.get() == null)
fail("timeout!");
}
assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());
FleaseFuture f = fs.closeCell(CELL_ID, false);
f.get();
Thread.sleep(12000);
result.set(null);
fs.openCell(CELL_ID, new ArrayList(), false);
synchronized(result) {
if (result.get() == null)
result.wait(1000);
if (result.get() == null)
fail("timeout!");
}
assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());
fs.shutdown();
fs.waitForShutdown();
}
/**
* Test of createTimer method, of class FleaseStage.
*/
@Test
public void testGetState() throws Exception {
FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {
@Override
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
//ignore me
}
}, true, new FleaseViewChangeListenerInterface() {
@Override
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
fail(error.toString());
}
}, null);
FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
msg.setCellId(new ASCIIString("testcell"));
fs.start();
fs.waitForStartup();
FleaseFuture f = fs.openCell(new ASCIIString("testcell"), new ArrayList(), false);
final AtomicBoolean done = new AtomicBoolean(false);
f.get();
Thread.sleep(100);
Map<ASCIIString,FleaseMessage> m = fs.getLocalState();
// for (ASCIIString cellId : m.keySet()) {
// System.out.println("cell "+cellId+" "+m.get(cellId));
// }
fs.shutdown();
fs.waitForShutdown();
}
/**
* Test of createTimer method, of class FleaseStage.
*/
@Test
public void testCreateTimer() throws Exception {
FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {
@Override
public void sendMessage(FleaseMessage messages, InetSocketAddress recipient) {
//ignore me
}
}, true, new FleaseViewChangeListenerInterface() {
@Override
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
throw new UnsupportedOperationException("Not supported yet.");
}
}, null);
FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
msg.setCellId(new ASCIIString("testcell"));
fs.start();
fs.waitForStartup();
fs.createTimer(msg, TimeSync.getLocalSystemTime()+20);
Thread.sleep(100);
fs.shutdown();
fs.waitForShutdown();
}
}

View File

@@ -0,0 +1,280 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
import org.xtreemfs.foundation.util.FSUtils;
/**
*
* @author bjko
*/
public class MasterEpochTest {
private static FleaseConfig cfg;
private static File testDir;
@BeforeClass
public static void setUpClass() {
Logging.start(Logging.LEVEL_WARN, Category.all);
TimeSync.initializeLocal(50);
cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5, true, 0, true);
testDir = new File("/tmp/xtreemfs-test/");
}
@Before
public void setUp() throws Exception {
FSUtils.delTree(testDir);
testDir.mkdirs();
}
@After
public void tearDown() throws Exception {
}
/**
* Test of createTimer method, of class FleaseStage.
*/
@Test
public void testOpenAndGetLease() throws Exception {
final ASCIIString CELL_ID = new ASCIIString("testcell");
final AtomicReference<Flease> result = new AtomicReference();
FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {
@Override
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
//ignore me
}
}, true, new FleaseViewChangeListenerInterface() {
@Override
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
// System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder());
synchronized (result) {
result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber()));
result.notify();
}
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
fail(error.toString());
}
}, new MasterEpochHandlerInterface() {
long masterEpochNum = 0;
@Override
public void sendMasterEpoch(FleaseMessage response, Continuation callback) {
// System.out.println("sending: "+masterEpochNum);
response.setMasterEpochNumber(masterEpochNum);
callback.processingFinished();
}
@Override
public void storeMasterEpoch(FleaseMessage request, Continuation callback) {
masterEpochNum = request.getMasterEpochNumber();
// System.out.println("storing: "+masterEpochNum);
callback.processingFinished();
}
});
FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
msg.setCellId(CELL_ID);
fs.start();
fs.waitForStartup();
fs.openCell(CELL_ID, new ArrayList(),true);
synchronized(result) {
if (result.get() == null)
result.wait(1000);
if (result.get() == null)
fail("timeout!");
}
assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());
assertEquals(result.get().getMasterEpochNumber(),1);
FleaseFuture f = fs.closeCell(CELL_ID, false);
f.get();
Thread.sleep(12000);
result.set(null);
fs.openCell(CELL_ID, new ArrayList(), true);
synchronized(result) {
if (result.get() == null)
result.wait(1000);
if (result.get() == null)
fail("timeout!");
}
assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());
assertEquals(result.get().getMasterEpochNumber(),2);
fs.shutdown();
fs.waitForShutdown();
}
/**
* Test of createTimer method, of class FleaseStage.
*/
@Test
public void testSimpleMasterEpochHandler() throws Exception {
final ASCIIString CELL_ID = new ASCIIString("testcell");
final AtomicReference<Flease> result = new AtomicReference();
SimpleMasterEpochHandler meHandler = new SimpleMasterEpochHandler("/tmp/xtreemfs-test/");
meHandler.start();
meHandler.waitForStartup();
FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {
@Override
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
//ignore me
}
}, true, new FleaseViewChangeListenerInterface() {
@Override
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
// System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder());
synchronized (result) {
result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber()));
result.notify();
}
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
fail(error.toString());
}
}, meHandler);
FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
msg.setCellId(CELL_ID);
fs.start();
fs.waitForStartup();
fs.openCell(CELL_ID, new ArrayList(),true);
synchronized(result) {
if (result.get() == null)
result.wait(1000);
if (result.get() == null)
fail("timeout!");
}
assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());
assertEquals(1, result.get().getMasterEpochNumber());
FleaseFuture f = fs.closeCell(CELL_ID, false);
f.get();
fs.shutdown();
fs.waitForShutdown();
meHandler.shutdown();
meHandler.waitForShutdown();
Thread.sleep(12000);
//restart
meHandler = new SimpleMasterEpochHandler("/tmp/xtreemfs-test/");
meHandler.start();
meHandler.waitForStartup();
fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {
@Override
public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
//ignore me
}
}, true, new FleaseViewChangeListenerInterface() {
@Override
public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
}
},new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
// System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder());
synchronized (result) {
result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber()));
result.notify();
}
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
fail(error.toString());
}
}, meHandler);
fs.start();
fs.waitForStartup();
result.set(null);
fs.openCell(CELL_ID, new ArrayList(), true);
synchronized(result) {
if (result.get() == null)
result.wait(1000);
if (result.get() == null)
fail("timeout!");
}
assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());
assertEquals(result.get().getMasterEpochNumber(),2);
fs.shutdown();
fs.waitForShutdown();
}
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.acceptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.File;
import java.net.InetSocketAddress;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.FleaseConfig;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.comm.FleaseMessage.MsgType;
import org.xtreemfs.foundation.flease.comm.ProposalNumber;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
import org.xtreemfs.foundation.util.FSUtils;
/**
*
* @author bjko
*/
public class FleaseAcceptorTest {
private FleaseAcceptor acceptor;
private final static ASCIIString TESTCELL = new ASCIIString("testcell");
private static FleaseConfig cfg;
private static File testDir;
@BeforeClass
public static void setUpClass() {
testDir = new File("/tmp/xtreemfs-test/");
FSUtils.delTree(testDir);
testDir.mkdirs();
Logging.start(Logging.LEVEL_WARN, Category.all);
TimeSync.initializeLocal(50);
cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",1);
}
@Before
public void setUp() throws Exception {
acceptor = new FleaseAcceptor(new LearnEventListener() {
@Override
public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long me) {
}
}, cfg, "/tmp/xtreemfs-test/", true);
}
@After
public void tearDown() throws Exception {
acceptor.shutdown();
}
@Test
public void testPrepAccLearn() {
FleaseMessage prep = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE);
prep.setCellId(TESTCELL);
prep.setProposalNo(new ProposalNumber(1, 1));
prep.setSendTimestamp(TimeSync.getLocalSystemTime());
prep.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000);
prep.setLeaseHolder(new ASCIIString("me"));
FleaseMessage response = acceptor.processMessage(prep);
assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType());
prep = new FleaseMessage(MsgType.MSG_ACCEPT,prep);
prep.setSendTimestamp(TimeSync.getLocalSystemTime());
response = acceptor.processMessage(prep);
assertEquals(MsgType.MSG_ACCEPT_ACK,response.getMsgType());
prep = new FleaseMessage(MsgType.MSG_LEARN,prep);
prep.setSendTimestamp(TimeSync.getLocalSystemTime());
response = acceptor.processMessage(prep);
assertNull(response);
}
@Test
public void testConcurrentProposal() {
FleaseMessage prep1 = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE);
prep1.setCellId(TESTCELL);
prep1.setProposalNo(new ProposalNumber(1, 1));
prep1.setSendTimestamp(TimeSync.getLocalSystemTime());
prep1.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000);
prep1.setLeaseHolder(new ASCIIString("me1"));
FleaseMessage prep2 = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE);
prep2.setCellId(TESTCELL);
prep2.setProposalNo(new ProposalNumber(1, 2));
prep2.setSendTimestamp(TimeSync.getLocalSystemTime());
prep2.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000);
prep2.setLeaseHolder(new ASCIIString("me2"));
FleaseMessage response = acceptor.processMessage(prep1);
assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType());
response = acceptor.processMessage(prep2);
assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType());
prep1 = new FleaseMessage(MsgType.MSG_ACCEPT,prep1);
prep1.setSendTimestamp(TimeSync.getLocalSystemTime());
response = acceptor.processMessage(prep1);
assertEquals(MsgType.MSG_ACCEPT_NACK,response.getMsgType());
}
@Test
public void testGetLease() {
FleaseMessage prep2 = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE);
prep2.setCellId(TESTCELL);
prep2.setProposalNo(new ProposalNumber(1, 2));
prep2.setSendTimestamp(TimeSync.getLocalSystemTime());
prep2.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000);
prep2.setLeaseHolder(new ASCIIString("me2"));
FleaseMessage response = acceptor.processMessage(prep2);
assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType());
prep2 = new FleaseMessage(MsgType.MSG_ACCEPT,prep2);
prep2.setSendTimestamp(TimeSync.getLocalSystemTime());
response = acceptor.processMessage(prep2);
assertEquals(MsgType.MSG_ACCEPT_ACK,response.getMsgType());
FleaseMessage lease = acceptor.getLocalLeaseInformation(TESTCELL);
assertNull(lease);
prep2 = new FleaseMessage(MsgType.MSG_LEARN,prep2);
prep2.setSendTimestamp(TimeSync.getLocalSystemTime());
response = acceptor.processMessage(prep2);
assertNull(response);
lease = acceptor.getLocalLeaseInformation(TESTCELL);
assertNotNull(lease);
assertEquals(new ASCIIString("me2"),lease.getLeaseHolder());
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.comm;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.buffer.BufferPool;
import org.xtreemfs.foundation.buffer.ReusableBuffer;
import static org.junit.Assert.*;
/**
*
* @author bjko
*/
public class FleaseMessageTest {
public FleaseMessageTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void testSerialization() throws Exception {
FleaseMessage m1 = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN);
m1.setCellId(new ASCIIString("testcell"));
m1.setLeaseHolder(new ASCIIString("yagga"));
m1.setLeaseTimeout(123456789l);
m1.setPrevProposalNo(new ProposalNumber(12, 178743687));
m1.setProposalNo(new ProposalNumber(15, 736456));
m1.setSendTimestamp(49789834);
m1.setViewId(55685);
m1.setMasterEpochNumber(52455115211l);
final int size = m1.getSize();
ReusableBuffer rb = BufferPool.allocate(size);
m1.serialize(rb);
rb.flip();
FleaseMessage m2 = new FleaseMessage(rb);
assertEquals(m1.getCellId(),m2.getCellId());
assertEquals(m1.getLeaseHolder(),m2.getLeaseHolder());
assertEquals(m1.getLeaseTimeout(),m2.getLeaseTimeout());
assertEquals(m1.getMsgType(),m2.getMsgType());
assertEquals(m1.getPrevProposalNo().getProposalNo(),m2.getPrevProposalNo().getProposalNo());
assertEquals(m1.getPrevProposalNo().getSenderId(),m2.getPrevProposalNo().getSenderId());
assertEquals(m1.getProposalNo().getProposalNo(),m2.getProposalNo().getProposalNo());
assertEquals(m1.getProposalNo().getSenderId(),m2.getProposalNo().getSenderId());
assertEquals(m1.getSendTimestamp(),m2.getSendTimestamp());
assertEquals(m1.getViewId(),m2.getViewId());
assertEquals(m1.getMasterEpochNumber(),m2.getMasterEpochNumber());
}
}

View File

@@ -0,0 +1,328 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.flease.proposer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.Flease;
import org.xtreemfs.foundation.flease.FleaseConfig;
import org.xtreemfs.foundation.flease.FleaseStatusListener;
import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptor;
import org.xtreemfs.foundation.flease.acceptor.LearnEventListener;
import org.xtreemfs.foundation.flease.comm.FleaseCommunicationInterface;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
import org.xtreemfs.foundation.util.FSUtils;
/**
*
* @author bjko
*/
public class FleaseProposerTest {
private FleaseAcceptor acceptor;
private FleaseProposer proposer;
private final static ASCIIString TESTCELL = new ASCIIString("testcell");
private static FleaseConfig cfg;
private static File testDir;
private static AtomicReference<Flease> result;
@BeforeClass
public static void setUpClass() throws Exception {
testDir = new File("/tmp/xtreemfs-test/");
FSUtils.delTree(testDir);
testDir.mkdirs();
result = new AtomicReference();
Logging.start(Logging.LEVEL_WARN, Category.all);
TimeSync.initializeLocal(50);
cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5);
}
@Before
public void setUp() throws Exception {
acceptor = new FleaseAcceptor(new LearnEventListener() {
@Override
public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long me) {
}
}, cfg, "/tmp/xtreemfs-test/", true);
proposer = new FleaseProposer(cfg, acceptor, new FleaseCommunicationInterface() {
@Override
public void sendMessage(FleaseMessage msg, InetSocketAddress receiver) throws IOException {
}
@Override
public void requestTimer(FleaseMessage msg, long timestamp) {
if (msg.getMsgType() == FleaseMessage.MsgType.EVENT_RESTART) {
long wait = timestamp - TimeSync.getLocalSystemTime();
try {
Thread.sleep(wait);
} catch (InterruptedException ex) {
Logger.getLogger(FleaseProposerTest.class.getName()).log(Level.SEVERE, null, ex);
}
try {
proposer.processMessage(msg);
} catch (Exception ex) {
fail(ex.toString());
}
}
}
}, new FleaseStatusListener() {
@Override
public void statusChanged(ASCIIString cellId, Flease lease) {
// System.out.println("result: "+lease.getLeaseHolder());
synchronized (result) {
result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber()));
result.notify();
}
}
@Override
public void leaseFailed(ASCIIString cellId, FleaseException error) {
// System.out.println("failed: "+error);
fail(error.toString());
}
}, new LearnEventListener() {
@Override
public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long me) {
throw new UnsupportedOperationException("Not supported yet.");
}
},null,null);
}
@After
public void tearDown() throws Exception {
}
@Test
public void testGetLease() throws Exception {
proposer.openCell(TESTCELL, new ArrayList(), false, 0);
Thread.sleep(100);
FleaseProposerCell cell = proposer.cells.get(TESTCELL);
assertEquals(TESTCELL,cell.getMessageSent().getCellId());
assertEquals(cfg.getIdentity(),cell.getMessageSent().getLeaseHolder());
assertTrue(cell.getMessageSent().getLeaseTimeout() > TimeSync.getGlobalTime());
}
/*public void testHandoverLease() throws Exception {
proposer.openCell(TESTCELL, new ArrayList(),false);
Thread.sleep(100);
FleaseProposerCell cell = proposer.cells.get(TESTCELL);
assertEquals(TESTCELL,cell.getMessageSent().getCellId());
assertEquals(cfg.getIdentity(),cell.getMessageSent().getLeaseHolder());
assertTrue(cell.getMessageSent().getLeaseTimeout() > TimeSync.getGlobalTime());
final ASCIIString HANDOVER = new ASCIIString("HANDOVER");
proposer.handoverLease(TESTCELL, HANDOVER);
Thread.sleep(100);
cell = proposer.cells.get(TESTCELL);
assertEquals(TESTCELL,cell.getMessageSent().getCellId());
assertEquals(HANDOVER,cell.getMessageSent().getLeaseHolder());
assertTrue(cell.getMessageSent().getLeaseTimeout() > TimeSync.getGlobalTime());
}*/
// public void testPriorProposal() throws Exception {
//
// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA");
// final AtomicBoolean finished = new AtomicBoolean(false);
//
// //initialize the acceptor
// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_ACCEPT);
// tmp.setCellId(TESTCELL);
// tmp.setProposalNo(new ProposalNumber(10, 123456));
// tmp.setLeaseHolder(otherId);
// tmp.setLeaseTimeout(TimeSync.getGlobalTime()-20000);
// tmp.setSendTimestamp(TimeSync.getGlobalTime());
// acceptor.processMessage(tmp);
//
// tmp.setCellId(TESTCELL);
// tmp.setProposalNo(new ProposalNumber(10, 123456));
// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000);
// tmp.setSendTimestamp(TimeSync.getGlobalTime());
// acceptor.processMessage(tmp);
//
// proposer.openCell(TESTCELL, new ArrayList<InetSocketAddress>(),false);
//
// System.out.println("start acquire lease...");
// proposer.acquireLease(TESTCELL, new FleaseListener() {
//
// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) {
// System.out.println("got lease!");
// assertEquals(TESTCELL,cellId);
// assertEquals(otherId,leaseHolder);
// finished.set(true);
// }
//
// public void proposalFailed(ASCIIString cellId, Throwable cause) {
// System.out.println("failed!");
// fail(cause.toString());
// }
// });
//
//
// }
//
//
// public void testPriorProposal2() throws Exception {
//
// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA");
// final AtomicBoolean finished = new AtomicBoolean(false);
//
// //initialize the acceptor
// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN);
// tmp.setCellId(TESTCELL);
// tmp.setProposalNo(new ProposalNumber(10, 123456));
// tmp.setLeaseHolder(otherId);
// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000);
// tmp.setSendTimestamp(TimeSync.getGlobalTime());
// acceptor.processMessage(tmp);
//
// tmp.setCellId(TESTCELL);
// tmp.setProposalNo(new ProposalNumber(10, 123456));
// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000);
// tmp.setSendTimestamp(TimeSync.getGlobalTime());
// acceptor.processMessage(tmp);
//
// proposer.openCell(TESTCELL, new ArrayList<InetSocketAddress>(),false);
//
// System.out.println("start acquire lease...");
// proposer.acquireLease(TESTCELL, new FleaseListener() {
//
// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) {
// System.out.println("got lease!");
// assertEquals(TESTCELL,cellId);
// assertEquals(otherId,leaseHolder);
// finished.set(true);
// }
//
// public void proposalFailed(ASCIIString cellId, Throwable cause) {
// System.out.println("failed!");
// fail(cause.toString());
// }
// });
//
//
// }
//
// public void testValidLease() throws Exception {
//
// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA");
// final AtomicBoolean finished = new AtomicBoolean(false);
//
// //initialize the acceptor
// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN);
// tmp.setCellId(TESTCELL);
// tmp.setProposalNo(new ProposalNumber(10, 123456));
// tmp.setLeaseHolder(otherId);
// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000);
// tmp.setSendTimestamp(TimeSync.getGlobalTime());
// acceptor.processMessage(tmp);
//
// proposer.openCell(TESTCELL, new ArrayList<InetSocketAddress>(),false);
//
// System.out.println("start acquire lease...");
// proposer.acquireLease(TESTCELL, new FleaseListener() {
//
// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) {
// System.out.println("got lease!");
// assertEquals(TESTCELL,cellId);
// assertEquals(otherId,leaseHolder);
// finished.set(true);
// }
//
// public void proposalFailed(ASCIIString cellId, Throwable cause) {
// System.out.println("failed!");
// fail(cause.toString());
// }
// });
// }
//
// public void testLeaseInGP() throws Exception {
//
// System.out.println("TEST testLeaseInGP");
//
// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA");
// final AtomicBoolean finished = new AtomicBoolean(false);
//
// //initialize the acceptor
// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN);
// tmp.setCellId(TESTCELL);
// tmp.setProposalNo(new ProposalNumber(10, 123456));
// tmp.setLeaseHolder(otherId);
// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+100);
// tmp.setSendTimestamp(TimeSync.getGlobalTime());
// acceptor.processMessage(tmp);
//
// proposer.openCell(TESTCELL, new ArrayList<InetSocketAddress>(),false);
//
// System.out.println("start acquire lease...");
// proposer.acquireLease(TESTCELL, new FleaseListener() {
//
// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) {
// System.out.println("got lease!");
// assertEquals(TESTCELL,cellId);
// assertEquals(cfg.getIdentity(),leaseHolder);
// finished.set(true);
// }
//
// public void proposalFailed(ASCIIString cellId, Throwable cause) {
// System.out.println("failed!");
// fail(cause.toString());
// }
// });
//
//
// }
}

View File

@@ -0,0 +1,75 @@
<?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.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="Foundation" default="default" basedir=".">
<description>Builds, tests, and runs the project Foundation as part of the XtreemFS project.</description>
<import file="nbproject/build-impl-1.6.5.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="XtreemFS-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>

View File

@@ -0,0 +1,74 @@
<?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.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="Foundation" default="default" basedir=".">
<description>Builds, tests, and runs the project Foundation as part of the XtreemFS project.</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="XtreemFS-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>

89
java/foundation/build.xml Normal file
View File

@@ -0,0 +1,89 @@
<?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.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="Foundation" default="default" basedir=".">
<description>Builds, tests, and runs the project Foundation as part of the XtreemFS project.</description>
<import file="nbproject/build-impl.xml"/>
<import file="nbproject/profiler-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="XtreemFS-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.
-->
<!--
This target is required by the BabuDB replication plugin which uses only a subset
of the foundation code (the PBRPC communication infrastructure).
The generated .jar file contains the required files of the subset.
-->
<target name="pbrpc-jar" depends="compile">
<echo level="info">Creating PBRPC.jar.</echo>
<!-- Create a new JAR. -->
<jar destfile="dist/PBRPC.jar" basedir="build/classes">
<include name="org/xtreemfs/foundation/pbrpc/**/*.class"/>
<zipfileset dir="../../" includes="LICENSE" fullpath="/LICENSE"/>
</jar>
</target>
</project>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="../lib/protobuf-java-2.5.0.jar"/>
<classpathentry kind="lib" path="../lib/test/junit-4.11.jar"/>
<classpathentry kind="lib" path="../lib/test/hamcrest-core-1.3.jar"/>
<classpathentry kind="lib" path="../lib/commons-codec-1.3.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>xtreemfs_foundation</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,682 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- compilation
- jar
- execution
- debugging
- javadoc
- junit compilation
- junit execution
- junit debugging
- applet
- cleanup
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="XtreemFS-foundation-impl">
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
<target depends="-pre-init,-init-private" name="-init-user">
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
<condition property="manifest.available+main.class">
<and>
<isset property="manifest.available"/>
<isset property="main.class"/>
<not>
<equals arg1="${main.class}" arg2="" trim="true"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class}"/>
<isset property="libs.CopyLibs.classpath"/>
</and>
</condition>
<condition property="have.tests">
<or>
<available file="${test.src.dir}"/>
</or>
</condition>
<condition property="have.sources">
<or>
<available file="${src.dir}"/>
</or>
</condition>
<condition property="netbeans.home+have.tests">
<and>
<isset property="netbeans.home"/>
<isset property="have.tests"/>
</and>
</condition>
<condition property="no.javadoc.preview">
<and>
<isset property="javadoc.preview"/>
<isfalse value="${javadoc.preview}"/>
</and>
</condition>
<property name="run.jvmargs" value=""/>
<property name="javac.compilerargs" value=""/>
<property name="work.dir" value="${basedir}"/>
<condition property="no.deps">
<and>
<istrue value="${no.dependencies}"/>
</and>
</condition>
<property name="javac.debug" value="true"/>
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
<not>
<equals arg1="${javadoc.encoding}" arg2=""/>
</not>
</and>
</condition>
<property name="javadoc.encoding.used" value="${source.encoding}"/>
<property name="includes" value="**"/>
<property name="excludes" value=""/>
<property name="do.depend" value="false"/>
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
<condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
<and>
<isset property="jaxws.endorsed.dir"/>
<available file="nbproject/jaxws-build.xml"/>
</and>
</condition>
</target>
<target name="-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
<fail unless="src.dir">Must set src.dir</fail>
<fail unless="test.src.dir">Must set test.src.dir</fail>
<fail unless="build.dir">Must set build.dir</fail>
<fail unless="dist.dir">Must set dist.dir</fail>
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
<fail unless="dist.jar">Must set dist.jar</fail>
</target>
<target name="-init-macrodef-property">
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-javac">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="${empty.dir}" name="sourcepath"/>
<attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
<property location="${build.dir}/empty" name="empty.dir"/>
<mkdir dir="${empty.dir}"/>
<mkdir dir="@{gensrcdir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
<src>
<dirset dir="@{gensrcdir}">
<include name="*"/>
</dirset>
</src>
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
<customize/>
</javac>
</sequential>
</macrodef>
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<sequential>
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</depend>
</sequential>
</macrodef>
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
<pathconvert pathsep="," property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
<delete>
<files includes="${javac.includes.binary}"/>
</delete>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-junit">
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="**" name="testincludes"/>
<sequential>
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
<batchtest todir="${build.test.results.dir}">
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
<filename name="@{testincludes}"/>
</fileset>
</batchtest>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<jvmarg line="${run.jvmargs}"/>
</junit>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-nbjpda">
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="name"/>
<attribute default="${debug.classpath}" name="classpath"/>
<attribute default="" name="stopclassname"/>
<sequential>
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="dt_socket">
<classpath>
<path path="@{classpath}"/>
</classpath>
</nbjpdastart>
</sequential>
</macrodef>
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${build.classes.dir}" name="dir"/>
<sequential>
<nbjpdareload>
<fileset dir="@{dir}" includes="${fix.classes}">
<include name="${fix.includes}*.class"/>
</fileset>
</nbjpdareload>
</sequential>
</macrodef>
</target>
<target name="-init-debug-args">
<property name="version-output" value="java version &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;1.3"/>
</or>
</condition>
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
<istrue value="${have-jdk-older-than-1.4}"/>
</condition>
</target>
<target depends="-init-debug-args" name="-init-macrodef-debug">
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${main.class}" name="classname"/>
<attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="classname"/>
<attribute default="${run.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar compress="${jar.compress}" jarfile="${dist.jar}">
<j2seproject1:fileset dir="${build.classes.dir}"/>
</jar>
</presetdef>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
<!--
===================
COMPILATION SECTION
===================
-->
<target depends="init" name="deps-jar" unless="no.deps"/>
<target depends="init,deps-jar" name="-pre-pre-compile">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="-pre-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-depend">
<pathconvert property="build.generated.subdirs">
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</pathconvert>
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
<target name="-pre-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile/>
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
<!--
====================
JAR BUILDING SECTION
====================
-->
<target depends="init" name="-pre-pre-jar">
<dirname file="${dist.jar}" property="dist.jar.dir"/>
<mkdir dir="${dist.jar.dir}"/>
</target>
<target name="-pre-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
<j2seproject1:jar/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
<j2seproject1:jar manifest="${manifest.file}">
<j2seproject1:manifest>
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
</j2seproject1:manifest>
</j2seproject1:jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
</copylibs>
</target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
=================
-->
<target depends="init,compile" description="Run a main class." name="run">
<j2seproject1:java>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject1:java>
</target>
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
<target depends="init,-do-not-recompile,compile-single" name="run-single">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
</target>
<!--
=================
DEBUGGING SECTION
=================
-->
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
</target>
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
</target>
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
</target>
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
<j2seproject1:nbjpdareload/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
<!--
===============
JAVADOC SECTION
===============
-->
<target depends="init" name="-javadoc-build">
<mkdir dir="${dist.javadoc.dir}"/>
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
<classpath>
<path path="${javac.classpath}"/>
</classpath>
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="**/*.java"/>
</fileset>
</javadoc>
</target>
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
</target>
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
<!--
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
<mkdir dir="${build.test.classes.dir}"/>
</target>
<target name="-pre-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-test-depend">
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
<target name="-pre-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
<!--
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target depends="init" if="have.tests" name="-pre-test-run">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
<target depends="init" if="have.tests" name="-pre-test-run-single">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
<delete file="${test.report.file}"/>
<mkdir dir="${build.test.results.dir}"/>
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
<customize>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<arg value="${test.class}"/>
<arg value="showoutput=true"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
<!--
=========================
APPLET EXECUTION SECTION
=========================
-->
<target depends="init,compile-single" name="run-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject1:java classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject1:java>
</target>
<!--
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject3:debug classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
<!--
===============
CLEANUP SECTION
===============
-->
<target depends="init" name="deps-clean" unless="no.deps"/>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="-post-clean">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
</project>

View File

@@ -0,0 +1,687 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- compilation
- jar
- execution
- debugging
- javadoc
- junit compilation
- junit execution
- junit debugging
- applet
- cleanup
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="XtreemFS-foundation-impl">
<fail message="Please build using Ant 1.7.1 or higher.">
<condition>
<not>
<antversion atleast="1.7.1"/>
</not>
</condition>
</fail>
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
<target depends="-pre-init,-init-private" name="-init-user">
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
<condition property="manifest.available+main.class">
<and>
<isset property="manifest.available"/>
<isset property="main.class"/>
<not>
<equals arg1="${main.class}" arg2="" trim="true"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class}"/>
<isset property="libs.CopyLibs.classpath"/>
</and>
</condition>
<condition property="have.tests">
<or>
<available file="${test.src.dir}"/>
</or>
</condition>
<condition property="have.sources">
<or>
<available file="${src.dir}"/>
</or>
</condition>
<condition property="netbeans.home+have.tests">
<and>
<isset property="netbeans.home"/>
<isset property="have.tests"/>
</and>
</condition>
<condition property="no.javadoc.preview">
<and>
<isset property="javadoc.preview"/>
<isfalse value="${javadoc.preview}"/>
</and>
</condition>
<property name="run.jvmargs" value=""/>
<property name="javac.compilerargs" value=""/>
<property name="work.dir" value="${basedir}"/>
<condition property="no.deps">
<and>
<istrue value="${no.dependencies}"/>
</and>
</condition>
<property name="javac.debug" value="true"/>
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
<not>
<equals arg1="${javadoc.encoding}" arg2=""/>
</not>
</and>
</condition>
<property name="javadoc.encoding.used" value="${source.encoding}"/>
<property name="includes" value="**"/>
<property name="excludes" value=""/>
<property name="do.depend" value="false"/>
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
<condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
<and>
<isset property="jaxws.endorsed.dir"/>
<available file="nbproject/jaxws-build.xml"/>
</and>
</condition>
</target>
<target name="-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
<fail unless="src.dir">Must set src.dir</fail>
<fail unless="test.src.dir">Must set test.src.dir</fail>
<fail unless="build.dir">Must set build.dir</fail>
<fail unless="dist.dir">Must set dist.dir</fail>
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
<fail unless="dist.jar">Must set dist.jar</fail>
</target>
<target name="-init-macrodef-property">
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-javac">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="${empty.dir}" name="sourcepath"/>
<attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
<property location="${build.dir}/empty" name="empty.dir"/>
<mkdir dir="${empty.dir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
<src>
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</src>
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
<customize/>
</javac>
</sequential>
</macrodef>
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<sequential>
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</depend>
</sequential>
</macrodef>
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
<pathconvert pathsep="," property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
<delete>
<files includes="${javac.includes.binary}"/>
</delete>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-junit">
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="**" name="testincludes"/>
<sequential>
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
<batchtest todir="${build.test.results.dir}">
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
<filename name="@{testincludes}"/>
</fileset>
</batchtest>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<jvmarg line="${run.jvmargs}"/>
</junit>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-nbjpda">
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="name"/>
<attribute default="${debug.classpath}" name="classpath"/>
<attribute default="" name="stopclassname"/>
<sequential>
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="dt_socket">
<classpath>
<path path="@{classpath}"/>
</classpath>
</nbjpdastart>
</sequential>
</macrodef>
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${build.classes.dir}" name="dir"/>
<sequential>
<nbjpdareload>
<fileset dir="@{dir}" includes="${fix.classes}">
<include name="${fix.includes}*.class"/>
</fileset>
</nbjpdareload>
</sequential>
</macrodef>
</target>
<target name="-init-debug-args">
<property name="version-output" value="java version &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;1.3"/>
</or>
</condition>
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
<istrue value="${have-jdk-older-than-1.4}"/>
</condition>
</target>
<target depends="-init-debug-args" name="-init-macrodef-debug">
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${main.class}" name="classname"/>
<attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="classname"/>
<attribute default="${run.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar compress="${jar.compress}" jarfile="${dist.jar}">
<j2seproject1:fileset dir="${build.classes.dir}"/>
</jar>
</presetdef>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
<!--
===================
COMPILATION SECTION
===================
-->
<target depends="init" name="deps-jar" unless="no.deps"/>
<target depends="init,deps-jar" name="-pre-pre-compile">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="-pre-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-depend">
<pathconvert property="build.generated.subdirs">
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</pathconvert>
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
<target name="-pre-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile/>
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
<!--
====================
JAR BUILDING SECTION
====================
-->
<target depends="init" name="-pre-pre-jar">
<dirname file="${dist.jar}" property="dist.jar.dir"/>
<mkdir dir="${dist.jar.dir}"/>
</target>
<target name="-pre-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
<j2seproject1:jar/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
<j2seproject1:jar manifest="${manifest.file}">
<j2seproject1:manifest>
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
</j2seproject1:manifest>
</j2seproject1:jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
</copylibs>
</target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
=================
-->
<target depends="init,compile" description="Run a main class." name="run">
<j2seproject1:java>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject1:java>
</target>
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
<target depends="init,-do-not-recompile,compile-single" name="run-single">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
</target>
<!--
=================
DEBUGGING SECTION
=================
-->
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
</target>
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
</target>
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
</target>
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
<j2seproject1:nbjpdareload/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
<!--
===============
JAVADOC SECTION
===============
-->
<target depends="init" name="-javadoc-build">
<mkdir dir="${dist.javadoc.dir}"/>
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
<classpath>
<path path="${javac.classpath}"/>
</classpath>
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="**/*.java"/>
</fileset>
</javadoc>
</target>
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
</target>
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
<!--
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
<mkdir dir="${build.test.classes.dir}"/>
</target>
<target name="-pre-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-test-depend">
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
<target name="-pre-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
<!--
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target depends="init" if="have.tests" name="-pre-test-run">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
<target depends="init" if="have.tests" name="-pre-test-run-single">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
<delete file="${test.report.file}"/>
<mkdir dir="${build.test.results.dir}"/>
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
<customize>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<arg value="${test.class}"/>
<arg value="showoutput=true"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
<!--
=========================
APPLET EXECUTION SECTION
=========================
-->
<target depends="init,compile-single" name="run-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject1:java classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject1:java>
</target>
<!--
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject3:debug classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
<!--
===============
CLEANUP SECTION
===============
-->
<target depends="init" name="deps-clean" unless="no.deps"/>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="-post-clean">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
</project>

View File

@@ -0,0 +1,11 @@
build.xml.data.CRC32=4a9eff70
build.xml.script.CRC32=ce2ddeb0
build.xml.stylesheet.CRC32=958a1d3e
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=beaaf17a
nbproject/build-impl.xml.script.CRC32=3e4625c6
nbproject/build-impl.xml.stylesheet.CRC32=78c6a6ee@1.38.1.45
nbproject/profiler-build-impl.xml.data.CRC32=4a9eff70
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- profiling
- applet profiling
-->
<project name="-profiler-impl" default="profile" basedir="..">
<target name="default" depends="profile" description="Build and profile the project."/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="profile-init" depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check"/>
<target name="-profile-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-profile-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-profile-init-macrodef-profile">
<macrodef name="resolve">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${env.@{value}}"/>
</sequential>
</macrodef>
<macrodef name="profile">
<attribute name="classname" default="${main.class}"/>
<element name="customize" optional="true"/>
<sequential>
<property environment="env"/>
<resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
<java fork="true" classname="@{classname}" dir="${profiler.info.dir}" jvm="${profiler.info.jvm}">
<jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg line="${profiler.info.jvmargs}"/>
<env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
<arg line="${application.args}"/>
<classpath>
<path path="${run.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper type="glob" from="run-sys-prop.*" to="*"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-profile-init-check" depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile">
<fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
<fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
</target>
<!--
=================
PROFILING SECTION
=================
-->
<target name="profile" if="netbeans.home" depends="profile-init,compile" description="Profile a project in the IDE.">
<nbprofiledirect>
<classpath>
<path path="${run.classpath}"/>
</classpath>
</nbprofiledirect>
<profile/>
</target>
<target name="profile-single" if="netbeans.home" depends="profile-init,compile-single" description="Profile a selected class in the IDE.">
<fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
<nbprofiledirect>
<classpath>
<path path="${run.classpath}"/>
</classpath>
</nbprofiledirect>
<profile classname="${profile.class}"/>
</target>
<!--
=========================
APPLET PROFILING SECTION
=========================
-->
<target name="profile-applet" if="netbeans.home" depends="profile-init,compile-single">
<nbprofiledirect>
<classpath>
<path path="${run.classpath}"/>
</classpath>
</nbprofiledirect>
<profile classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</profile>
</target>
<!--
=========================
TESTS PROFILING SECTION
=========================
-->
<target name="profile-test-single" if="netbeans.home" depends="profile-init,compile-test-single">
<nbprofiledirect>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
</nbprofiledirect>
<junit showoutput="true" fork="true" dir="${profiler.info.dir}" jvm="${profiler.info.jvm}" failureproperty="tests.failed" errorproperty="tests.failed">
<env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
<jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg line="${profiler.info.jvmargs}"/>
<test name="${profile.class}"/>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper type="glob" from="test-sys-prop.*" to="*"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
</junit>
</target>
</project>

View File

@@ -0,0 +1,82 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.run.all.processors=true
application.args=
application.title=Foundation
application.vendor=flangner
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/Foundation.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.bcprov-jdk16-139.jar=lib/bcprov-jdk16-139.jar
file.reference.cdaclient.jar=lib/cdaclient.jar
file.reference.junit-4.11.jar=../lib/test/junit-4.11.jar
file.reference.config.jar=lib/config.jar
file.reference.je-3.2.13.jar=lib/je-3.2.13.jar
file.reference.protobuf-java-2.5.0.jar=../lib/protobuf-java-2.5.0.jar
file.reference.xbean.jar=lib/xbean.jar
file.reference.commons-codec-1.3.jar=../lib/commons-codec-1.3.jar
includes=**
jar.compress=true
javac.classpath=\
${file.reference.commons-codec-1.3.jar}:\
${file.reference.protobuf-java-2.5.0.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
javac.source=1.6
javac.target=1.6
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit_4.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
jnlp.codebase.type=local
jnlp.enabled=false
jnlp.offline-allowed=false
jnlp.signed=false
main.class=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=-ea
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
src.dir=src
test.src.dir=test

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<buildExtensions xmlns="http://www.netbeans.org/ns/ant-build-extender/1">
<extension file="protobuf-build.xml" id="protobuf">
<dependency dependsOn="protobuf-code-generation" target="-pre-pre-compile"/>
</extension>
</buildExtensions>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>XtreemFS-foundation</name>
<minimum-ant-version>1.6.5</minimum-ant-version>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
<references xmlns="http://www.netbeans.org/ns/ant-project-references/1"/>
</configuration>
</project>

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2010 by Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
/**
*
* @author bjko
*/
public final class ClientLease implements Cloneable {
/**
* Default time span for the client lease validity.
* Must be smaller than a intra-OSD lease, if replication is
* active!
*/
public static final long LEASE_VALIDITY = 15000;
/**
* Indicates that a lease spans to EOF "append lease".
* a lease from 0 to -1 spans the whole file, even if data is appended.
*/
public static final long TO_EOF = -1;
/**
* timestamp when the lease expires
*/
private long firstObject;
/**
* last object the lease is valid for
*/
private long lastObject;
/**
* UUID of the client owning the lease
*/
private String clientId;
/**
* timestamp when the lease expires (in seconds since 01/01/70)
* must be XtreemFS global time!
*/
private long expires;
/**
* fileId this lease was issued for
*/
private final String fileId;
/**
* sequenceNo, used to generate unique leaseId = fileId+"/"+sequenceNo
*/
private long sequenceNo;
/**
* lease type/operation
*/
private String operation;
public static final String EXCLUSIVE_LEASE = "w";
public ClientLease(final String fileId) {
this.fileId = fileId;
}
/**
* Checks if two leases have conflicting (i.e. overlapping ranges)
* @param other other lease for the same file
* @return true, if there is an overlap in the ranges
*/
public boolean isConflicting(ClientLease other) {
//checks
if ( ((this.lastObject < other.firstObject) && (this.lastObject != TO_EOF)) ||
((other.lastObject < this.firstObject) && (other.lastObject != TO_EOF)) ) {
return false;
} else {
return true;
}
}
@Override
public ClientLease clone() {
ClientLease l = new ClientLease(this.fileId);
l.clientId = this.clientId;
l.expires = this.expires;
l.firstObject = this.firstObject;
l.lastObject = this.lastObject;
l.operation = this.operation;
l.sequenceNo = this.sequenceNo;
return l;
}
public long getFirstObject() {
return firstObject;
}
public void setFirstObject(long firstObject) {
this.firstObject = firstObject;
}
public long getLastObject() {
return lastObject;
}
public void setLastObject(long lastObject) {
this.lastObject = lastObject;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public long getExpires() {
return expires;
}
public void setExpires(long expires) {
this.expires = expires;
}
public String getFileId() {
return fileId;
}
public long getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(long sequenceNo) {
this.sequenceNo = sequenceNo;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2010 by Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
import java.util.Map;
/**
*
* @author bjko
*/
public class CrashReporter {
public static void reportXtreemFSCrash(String report) {
/*try {
URL u = new URL("http://www.xtreemfs.org/dump/dump.php?srv=server");
HttpURLConnection con = (HttpURLConnection) u.openConnection();
con.setRequestMethod("PUT");
con.setDoOutput(true);
con.connect();
OutputStream os = con.getOutputStream();
os.write(report.getBytes());
os.flush();
os.close();
InputStream is = con.getInputStream();
is.available();
is.close();
} catch (Throwable th) {
System.out.println("cannot send crash report: "+th);
}*/
}
public static String createCrashReport(String service, String version, Throwable cause) {
try {
StringBuilder report = new StringBuilder();
report.append("----------------------------------------------------------------\n");
report.append("We are sorry, but your "+service+" has crashed. To report this bug\n");
report.append("please go to http://www.xtreemfs.org and file an issue and attach\n");
report.append("this crash report.\n\n");
report.append("service: ");
report.append(service);
report.append(" version: ");
report.append(version);
report.append("\n");
report.append("JVM version: ");
report.append(System.getProperty("java.version"));
report.append(" ");
report.append(System.getProperty("java.vendor"));
report.append(" on ");
report.append(System.getProperty("os.name"));
report.append(" ");
report.append(System.getProperty("os.version"));
report.append("\n");
report.append("exception: ");
report.append(cause.toString());
report.append("\n");
for (StackTraceElement elem : cause.getStackTrace()) {
report.append(elem.toString());
report.append("\n");
}
if (cause.getCause() != null) {
report.append("\nroot cause: ");
report.append(cause.getCause());
report.append("\n");
for (StackTraceElement elem : cause.getCause().getStackTrace()) {
report.append(elem.toString());
report.append("\n");
}
}
reportThreadStates(report);
report.append("----------------------------------------------------------------\n");
return report.toString();
} catch (Exception ex) {
ex.printStackTrace();
return "Could not write crash report for: "+service+","+version+","+cause+" due to "+ex;
}
}
/** Logs the stack trace of each thread into {@code report}. */
public static void reportThreadStates(StringBuilder report) {
report.append("\n--- THREAD STATES ---\n");
final Map<Thread,StackTraceElement[]> traces = Thread.getAllStackTraces();
for (Thread t : traces.keySet()) {
report.append("thread: ");
report.append(t.getName());
report.append("\n");
for (StackTraceElement e : traces.get(t)) {
report.append(e.toString());
report.append("\n");
}
report.append("\n");
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* This class implements a LRU cache
*
* @author jmalo
*/
public class LRUCache<K,V> extends LinkedHashMap<K,V> {
private static final long serialVersionUID = -4673214355284364245L;
private int maximumSize;
/** Creates a new instance of LRUCache */
public LRUCache(int size) {
super(size, (float)0.75, true);
maximumSize = size;
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maximumSize;
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2010 by Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
/**
* Notifies a process of a life cycle event.
*
* @author stender
*
*/
public interface LifeCycleListener {
public void startupPerformed();
public void shutdownPerformed();
public void crashPerformed(Throwable cause);
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2008-2010 by Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
* A base class for threads representing a life cycle. It offers methods for
* blocking other threads until a certain life cycle event has occurred. It
* currently supports two life cycle-related events: startup and shutdown.
*
* @author stender
*
*/
public class LifeCycleThread extends Thread {
private final Object startLock;
private final Object stopLock;
private boolean started;
private boolean stopped;
private Exception exc;
private LifeCycleListener listener;
public LifeCycleThread(String name) {
super(name);
startLock = new Object();
stopLock = new Object();
}
/**
* This method should be invoked by subclasses when the startup procedure
* has been completed.
*/
protected void notifyStarted() {
if (Logging.isInfo())
Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "Thread %s started", Thread
.currentThread().getName());
synchronized (startLock) {
started = true;
startLock.notifyAll();
if (listener != null)
listener.startupPerformed();
}
}
/**
* This method should be invoked by subclasses when the shutdown procedure
* has been completed.
*/
protected void notifyStopped() {
if (Logging.isInfo())
Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "Thread %s terminated", Thread
.currentThread().getName());
synchronized (stopLock) {
stopped = true;
stopLock.notifyAll();
if (listener != null)
listener.shutdownPerformed();
}
}
/**
* This method should be invoked by subclasses when the thread has crashed.
*/
protected void notifyCrashed(Throwable exc) {
Logging.logMessage(Logging.LEVEL_CRIT, this, "service ***CRASHED***, shutting down");
Logging.logError(Logging.LEVEL_CRIT, this, exc);
synchronized (startLock) {
this.exc = exc instanceof Exception ? (Exception) exc : new Exception(exc);
started = true;
startLock.notifyAll();
}
synchronized (stopLock) {
this.exc = exc instanceof Exception ? (Exception) exc : new Exception(exc);
stopped = true;
stopLock.notifyAll();
}
if (listener != null)
listener.crashPerformed(exc);
}
/**
* Synchronously waits for a notification indicating that the startup
* procedure has been completed.
*
* @throws Exception
* if an error occurred during the startup procedure
*/
public void waitForStartup() throws Exception {
synchronized (startLock) {
while (!started)
startLock.wait();
if (exc != null && listener == null)
throw exc;
}
}
/**
* Synchronously waits for a notification indicating that the shutdown
* procedure has been completed.
*
* @throws Exception
* if an error occurred during the shutdown procedure
*/
public void waitForShutdown() throws Exception {
synchronized (stopLock) {
if (!started)
return;
while (!stopped)
try {
stopLock.wait();
} catch (InterruptedException e) {
// In case this thread executes notifyCrashed(), he will
// probably interrupt itself. However, this should not
// interfere with the notifyCrashed() procedure and
// therefore we swallow this exception.
if (listener == null) {
throw e;
}
}
if (exc != null && listener == null)
throw exc;
}
}
/**
* Terminates the thread. This method should be overridden in subclasses.
* @throws Exception if an error occurred
*/
public void shutdown() throws Exception {
}
/**
* Sets a listener waiting for life cycle events.
*
* @param listener
* the listener
*/
public void setLifeCycleListener(LifeCycleListener listener) {
this.listener = listener;
}
}

View File

@@ -0,0 +1,407 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
import org.xtreemfs.foundation.util.OutputUtils;
/**
* Encapsulates the SSLOptions for the connections of pinky and speedy
*
* @author clorenz
*/
public class SSLOptions {
/**
* a Java JKS Keystore
*/
public final static String JKS_CONTAINER = "JKS";
/**
* a PKCS12 Keystore
*/
public final static String PKCS12_CONTAINER = "PKCS12";
/**
* Default SSL/TLS Protocol to use when no or an invalid protocol was specified
*/
public final static String DEFAULT_SSL_PROTOCOL = "TLS";
/**
* file with the private key and the public cert for the server
*/
private final InputStream serverCredentialFile;
/**
* file with trusted public certs
*/
private final InputStream trustedCertificatesFile;
/**
* passphrase of the server credential file
*/
private final char[] serverCredentialFilePassphrase;
/**
* passphrase of the trusted certificates file
*/
private final char[] trustedCertificatesFilePassphrase;
/**
* using symmetric encryption or only authenticating via certs
*/
private boolean authenticationWithoutEncryption;
/**
* file format of the server credential file
*/
private final String serverCredentialFileContainer;
/**
* file format of the trusted certificates file
*/
private final String trustedCertificatesFileContainer;
/**
* knows the used certs and more
*/
private final SSLContext sslContext;
private final boolean useFakeSSLMode;
public SSLOptions(InputStream serverCredentialFile, String serverCredentialFilePassphrase,
String serverCredentialFileContainer, InputStream trustedCertificatesFile,
String trustedCertificatesFilePassphrase, String trustedCertificatesFileContainer,
boolean authenticationWithoutEncryption, boolean useFakeSSLMode, String sslProtocolString,
TrustManager trustManager) throws IOException {
this.serverCredentialFile = serverCredentialFile;
this.trustedCertificatesFile = trustedCertificatesFile;
if (serverCredentialFilePassphrase != null)
this.serverCredentialFilePassphrase = serverCredentialFilePassphrase.toCharArray();
else
this.serverCredentialFilePassphrase = null;
if (trustedCertificatesFilePassphrase != null)
this.trustedCertificatesFilePassphrase = trustedCertificatesFilePassphrase.toCharArray();
else
this.trustedCertificatesFilePassphrase = null;
this.serverCredentialFileContainer = serverCredentialFileContainer;
this.trustedCertificatesFileContainer = trustedCertificatesFileContainer;
this.authenticationWithoutEncryption = authenticationWithoutEncryption;
this.useFakeSSLMode = useFakeSSLMode;
sslContext = createSSLContext(sslProtocolStringToProtocol(sslProtocolString), trustManager);
}
/**
* Create/initialize the SSLContext with key material
*
* @param trustManager
* the trust manager for the SSL context (may be
* <code>null</code>)
* @return the created and initialized SSLContext
* @throws IOException
*/
private SSLContext createSSLContext(String sslProtocol, TrustManager trustManager) throws IOException {
SSLContext sslContext = null;
try {
// First initialize the key and trust material.
KeyStore ksKeys = KeyStore.getInstance(serverCredentialFileContainer);
ksKeys.load(serverCredentialFile, serverCredentialFilePassphrase);
// KeyManager's decide which key material to use.
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ksKeys, serverCredentialFilePassphrase);
// There are quite a few issues with the OpenJDK PKCS11 provider in combination with NSS,
// so remove it no matter what the OpenJDK version is.
if ("OpenJDK Runtime Environment".equals(System.getProperty("java.runtime.name"))) {
try {
Security.removeProvider("SunPKCS11-NSS");
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "Successfully removed faulty security provider 'SunPKCS11-NSS'.");
}
} catch(SecurityException e) {
Logging.logMessage(Logging.LEVEL_WARN, this,
"Could not remove security provider 'SunPKCS11-NSS'. This might cause TLS connections to time out. " +
"Known to affect multiple OpenJDK / NSS version combinations.");
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "%s:\n%s", e.getMessage(), OutputUtils.stackTraceToString(e));
}
}
}
// Re-enable disabled algorithms if the user requests it.
final String defaultDisabledAlgorithms = Security.getProperty("jdk.tls.disabledAlgorithms");
removeDisabledEntailedProtocolSupportForProtocol(sslProtocol);
try {
sslContext = SSLContext.getInstance(sslProtocol);
} catch (NoSuchAlgorithmException e) {
Logging.logMessage(Logging.LEVEL_WARN, this, "Unsupported algorithm '%s', defaulting to '%s'.",
sslProtocol, DEFAULT_SSL_PROTOCOL);
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "%s:\n%s", e.getMessage(), OutputUtils.stackTraceToString(e));
}
// Reset disabled algorithms because the context could not be created.
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "Trying to reset disabled algorithms.");
}
try {
Security.setProperty("jdk.tls.disabledAlgorithms", defaultDisabledAlgorithms);
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "Successfully reset disabled algorithms.");
}
} catch (SecurityException e1) {
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "Could not reset disabled algorithms: %s", OutputUtils.stackTraceToString(e1));
}
}
// Setup everything anew for the default SSL protocol.
removeDisabledEntailedProtocolSupportForProtocol(DEFAULT_SSL_PROTOCOL);
sslContext = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL);
}
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "Disabling the following algorithms: %s", Security.getProperty("jdk.tls.disabledAlgorithms"));
}
if (trustManager != null) {
// if a user-defined trust manager is set ...
trustManager.init(trustedCertificatesFileContainer, trustedCertificatesFile,
trustedCertificatesFilePassphrase);
sslContext.init(kmf.getKeyManagers(), new TrustManager[] { trustManager }, null);
} else if (trustedCertificatesFileContainer.equals("none")) {
TrustManager[] myTMs = new TrustManager[] { new NoAuthTrustStore() };
sslContext.init(kmf.getKeyManagers(), myTMs, null);
} else {
// TrustManager's decide whether to allow connections.
KeyStore ksTrust = null;
if (trustedCertificatesFileContainer.equals("none")) {
ksTrust = KeyStore.getInstance(KeyStore.getDefaultType());
} else {
ksTrust = KeyStore.getInstance(trustedCertificatesFileContainer);
ksTrust.load(trustedCertificatesFile, trustedCertificatesFilePassphrase);
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ksTrust);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
}
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
}
return sslContext;
}
public boolean isAuthenticationWithoutEncryption() {
return this.authenticationWithoutEncryption;
}
public void setAuthenticationWithoutEncryption(boolean authenticationWithoutEncryption) {
this.authenticationWithoutEncryption = authenticationWithoutEncryption;
}
public InputStream getServerCredentialFile() {
return this.serverCredentialFile;
}
public String getServerCredentialFileContainer() {
return this.serverCredentialFileContainer;
}
public String getServerCredentialFilePassphrase() {
return this.serverCredentialFilePassphrase.toString();
}
public InputStream getTrustedCertificatesFile() {
return this.trustedCertificatesFile;
}
public String getTrustedCertificatesFileContainer() {
return this.trustedCertificatesFileContainer;
}
public String getTrustedCertificatesFilePassphrase() {
return this.trustedCertificatesFilePassphrase.toString();
}
public SSLContext getSSLContext() {
return this.sslContext;
}
public boolean isFakeSSLMode() {
return this.useFakeSSLMode;
}
public String getSSLProtocol() {
return sslContext.getProtocol();
}
public boolean isSSLEngineProtocolSupported(String sslEngineProtocol) {
// Protocol names in JDK 5, 6: SSLv2Hello, SSLv3, TLSv1
// Additionally in JDK 7, 8: TLSv1.2
// TLSv1.1 seems to depend on the vendor
String sslProtocol = getSSLProtocol();
if ("SSLv3".equals(sslProtocol)) {
return "SSLv3".equals(sslEngineProtocol);
} else if ("TLS".equals(sslProtocol)) {
return "SSLv3".equals(sslEngineProtocol) ||
"TLSv1".equals(sslEngineProtocol) ||
"TLSv1.1".equals(sslEngineProtocol) ||
"TLSv1.2".equals(sslEngineProtocol);
} else if ("TLSv1".equals(sslProtocol)) {
return "TLSv1".equals(sslEngineProtocol);
} else if ("TLSv1.1".equals(sslProtocol)) {
return "TLSv1.1".equals(sslEngineProtocol);
} else if ("TLSv1.2".equals(sslProtocol)) {
return "TLSv1.2".equals(sslEngineProtocol);
} else {
return false;
}
}
private String sslProtocolStringToProtocol(String sslProtocolString) {
// SSL Context Protocol Strings:
// JDK 6: SSL, SSLv2, SSLv3, TLS, TLSv1
// additionally in JDK 7: TLSv1.2
// TLSv1.1 seems to depend on the vendor
if ("sslv3".equals(sslProtocolString)) {
return "SSLv3";
} else if ("ssltls".equals(sslProtocolString)) {
return "TLS";
} else if ("tlsv1".equals(sslProtocolString)) {
return "TLSv1";
} else if ("tlsv11".equals(sslProtocolString)) {
return "TLSv1.1";
} else if ("tlsv12".equals(sslProtocolString)) {
return "TLSv1.2";
} else {
if (sslProtocolString != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.net, this,
"Unknown SSL Context Protocol: '%s', defaulting to '%s'.",
sslProtocolString, DEFAULT_SSL_PROTOCOL);
}
return DEFAULT_SSL_PROTOCOL;
}
}
/**
* Removes all protocols that should be supported when using {@code sslProtocol} from the disabled
* algorithms list that is set as system default, e.g. in /usr/lib/jvm/default-java/jre/lib/security/java.security.
*
* @param sslProtocol
*/
private void removeDisabledEntailedProtocolSupportForProtocol(String sslProtocol) {
if (Security.getProperty("jdk.tls.disabledAlgorithms") == null) {
return; // no disabled algorithms, everything is allowed by default
}
String[] entailedSupportedProtocols = new String[] {};
if ("SSLv3".equals(sslProtocol)) {
entailedSupportedProtocols = new String[] { "SSLv3" };
} else if ("TLS".equals(sslProtocol)) {
entailedSupportedProtocols = new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" };
} else if ("TLSv1".equals(sslProtocol)) {
entailedSupportedProtocols = new String[] { "TLSv1" };
} else if ("TLSv1.1".equals(sslProtocol)) {
entailedSupportedProtocols = new String[] { "TLSv1.1" };
} else if ("TLSv1.2".equals(sslProtocol)) {
entailedSupportedProtocols = new String[] { "TLSv1.2" };
}
// For each protocol whose support is entailed by the requested protocol,
// remove it from the disabled algorithms list if possible.
for (String supportedSSLProtocol : entailedSupportedProtocols) {
if (Security.getProperty("jdk.tls.disabledAlgorithms").contains(supportedSSLProtocol)) {
Logging.logMessage(Logging.LEVEL_WARN, this,
"Algorithm '%s' is disabled in your java.security configuration file (see key 'jdk.tls.disabledAlgorithms'). " +
"Trying to enable algorithm '%s' manually as specified in your configuration file (see key 'ssl.protocol'). " +
"Consider using a newer SSL/TLS algorithm for your setup, " +
"as algorithm '%s' has been disabled by default because of security issues.",
supportedSSLProtocol, supportedSSLProtocol, supportedSSLProtocol);
try {
Security.setProperty("jdk.tls.disabledAlgorithms",
Security.getProperty("jdk.tls.disabledAlgorithms").replace(supportedSSLProtocol, "").replace(" ", ""));
if (Logging.isDebug()) {
Logging.logMessage(Logging.LEVEL_DEBUG, this, "Successfully removed algorithm '%s' from disabled algorithms.",
supportedSSLProtocol);
}
} catch (SecurityException e) {
Logging.logMessage(Logging.LEVEL_WARN, this, "Could not remove algorithm '%s' from disabled algorithm. " +
"This might cause SSL Handshake exceptions. For SSLv3 this is known to affect all JDKs fixing issue CVE-2014-3566.",
supportedSSLProtocol);
}
}
}
}
private static class NoAuthTrustStore implements TrustManager, X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// ignore
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// ignore
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
@Override
public void init(String trustedCertificatesFileContainer, InputStream trustedCertificatesFile,
char[] trustedCertificatesFilePassphrase) {
// ignore
}
}
public static interface TrustManager extends javax.net.ssl.TrustManager {
public void init(String trustedCertificatesFileContainer, InputStream trustedCertificatesFile,
char[] trustedCertificatesFilePassphrase);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2010 by Felix Langner,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
import java.net.InetSocketAddress;
import org.xtreemfs.foundation.pbrpc.client.RPCResponse;
/**
* Provides methods to synchronize with a XtreemFS TimeServer, usually provided
* by a DIR service.
*
* @author flangner
* @since 03/01/2010
*/
public interface TimeServerClient {
/**
* Requests the global time at the given server.
*
* @param server - if null, the default will be used.
* @return a {@link RPCResponse} future for an UNIX time-stamp.
*/
public long xtreemfs_global_time_get(InetSocketAddress server);
}

View File

@@ -0,0 +1,464 @@
/*
* Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
* A class that offers a local time w/ adjustable granularity and a global time
* based on the time reported by the DIR. Global time is adjusted periodically.
* This class should be used to minimize the number of calls to
* System.currentTimeMillis which is a costly system call on Linux. Moreover it
* offers a system-global time.
*
* @author bjko
*/
public final class TimeSync extends LifeCycleThread {
public enum ExtSyncSource {
XTREEMFS_DIR, GPSD, LOCAL_CLOCK
};
/**
* The maximum round trip time for a clock synchronization message between
* the <code>TimeSync</code> and the DIR. If the round trip time of a
* synchronization message exceeds this value, the message will be ignored.
*/
private static final int MAX_RTT = 1000;
/**
* A client used to synchronize clocks
*/
private TimeServerClient timeServerClient;
/**
* interval in ms to wait between to synchronizations.
*/
private volatile int timeSyncInterval;
/**
* interval between updates of the local system clock.
*
* If it's set to 0, the local renew by the thread is disabled and the time
* is read from the system on demand.
*/
private volatile int localTimeRenew;
private volatile ExtSyncSource syncSource;
private InetSocketAddress gpsdAddr;
/**
* local sys time as of last update
*/
private volatile long localSysTime;
/**
* drift between local clock and global time as of last resync() operation.
*/
private volatile long currentDrift;
/**
* set to true to stop thread
*/
private volatile boolean quit;
/**
* timestamp of last resync operation
*/
private volatile long lastSuccessfulSync;
/**
* Timestamp of the last resync attempt.
*
* @note No need to specify it as volatile since it's only used by run().
*/
private long lastSyncAttempt;
private volatile int syncRTT;
private volatile boolean syncSuccess;
private static TimeSync theInstance;
private final Pattern gpsdDatePattern;
private Socket gpsdSocket;
/**
* Creates a new instance of TimeSync
*
* @dir a directory server to use for synchronizing clocks, can be null for
* test setups only
*/
private TimeSync(ExtSyncSource source, TimeServerClient dir, InetSocketAddress gpsd, int timeSyncInterval, int localTimeRenew) {
super("TSync Thr");
setDaemon(true);
this.syncSuccess = false;
this.gpsdDatePattern = Pattern.compile("GPSD,D=(....)-(..)-(..)T(..):(..):(..)\\.(.+)Z");
init(source, dir, gpsd, timeSyncInterval, localTimeRenew);
}
/**
* Initializes the TimeSync with new parameters.
*
* @param source
* @param dir
* @param gpsd
* @param timeSyncInterval
* @param localTimeRenew
*/
public synchronized void init(ExtSyncSource source, TimeServerClient dir, InetSocketAddress gpsd, int timeSyncInterval, int localTimeRenew) {
this.localTimeRenew = localTimeRenew;
this.timeSyncInterval = timeSyncInterval;
this.timeServerClient = dir;
this.syncSource = source;
this.gpsdAddr = gpsd;
if (this.timeServerClient != null && this.timeSyncInterval != 0 && this.localTimeRenew != 0) {
this.localTimeRenew = 0;
Logging.logMessage(Logging.LEVEL_DEBUG, this,
"Disabled the periodic local time renew (set local_clock_renewal to 0)" +
" and using always the current system time as base since the time will be corrected by synchronizing with the DIR service.");
}
if (source == ExtSyncSource.GPSD) {
try {
if (gpsdSocket != null)
gpsdSocket.close();
gpsdSocket = new Socket();
gpsdSocket.setSoTimeout(2000);
gpsdSocket.setTcpNoDelay(true);
gpsdSocket.connect(gpsdAddr,2000);
} catch (IOException ex) {
Logging.logMessage(Logging.LEVEL_ERROR, this,"cannot connect to GPSd: "+ex);
gpsdSocket = null;
}
}
}
/**
* main loop
*/
@Override
public void run() {
TimeSync.theInstance = this;
notifyStarted();
String tsStatus;
if (localTimeRenew == 0) {
tsStatus = "using the local clock";
} else {
tsStatus = "using the local clock (precision is " + this.localTimeRenew + " ms)";
}
if (this.timeServerClient != null && timeSyncInterval != 0) {
tsStatus += " and remote sync every " + this.timeSyncInterval + " ms";
}
Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "TimeSync is running %s", tsStatus);
while (!quit) {
// Renew cached local time.
final long previousLocalSysTime = localSysTime;
localSysTime = System.currentTimeMillis();
if (localTimeRenew > 0 && previousLocalSysTime != 0) {
final long timeBetweenUpdates = Math.abs(localSysTime - previousLocalSysTime);
if (timeBetweenUpdates > 4 * localTimeRenew) {
Logging.logMessage(Logging.LEVEL_WARN, this,
"The granularity of the renewed local time could not be guaranteed" +
" since it took longer to retrieve the latest local time (%d ms) than configured (local_clock_renewal = %d)." +
" Maybe the system is under high I/O load and therefore scheduling threads takes longer than usual?",
timeBetweenUpdates,
localTimeRenew);
}
}
// Remote sync time.
if (timeSyncInterval != 0 && localSysTime - lastSyncAttempt > timeSyncInterval) {
resync();
}
if (!quit) {
//
try {
// If local refresh was disabled, use timeSyncInterval as sleep time.
long sleepTimeMs = localTimeRenew != 0 ? localTimeRenew : timeSyncInterval;
if (sleepTimeMs == 0) {
// If there is no need to run this thread at all, let it sleep for 10 minutes.
sleepTimeMs = 600000;
}
TimeSync.sleep(sleepTimeMs);
} catch (InterruptedException ex) {
break;
}
}
}
notifyStopped();
syncSuccess = false;
theInstance = null;
}
/**
* Initializes the time synchronizer. Note that only the first invocation of
* this method has an effect, any further invocations will be ignored.
*
* @param dir
* @param timeSyncInterval
* @param localTimeRenew
* @param dirAuthStr
*/
public static TimeSync initialize(TimeServerClient dir, int timeSyncInterval, int localTimeRenew) throws Exception {
if (theInstance != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, null, "time sync already running",
new Object[0]);
return theInstance;
}
TimeSync s = new TimeSync(ExtSyncSource.XTREEMFS_DIR, dir, null, timeSyncInterval, localTimeRenew);
s.start();
s.waitForStartup();
return s;
}
public static TimeSync initializeLocal(int localTimeRenew) {
if (theInstance != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, null, "time sync already running",
new Object[0]);
return theInstance;
}
TimeSync s = new TimeSync(ExtSyncSource.LOCAL_CLOCK, null, null, 0, localTimeRenew);
s.start();
return s;
}
public static TimeSync initializeGPSD(InetSocketAddress gpsd, int timeSyncInterval, int localTimeRenew) {
if (theInstance != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, null, "time sync already running",
new Object[0]);
return theInstance;
}
TimeSync s = new TimeSync(ExtSyncSource.GPSD, null, gpsd, timeSyncInterval, localTimeRenew);
s.start();
return s;
}
public void close() {
shutdown();
try {
waitForShutdown();
} catch (Exception e) {
Logging.logError(Logging.LEVEL_ERROR, null, e);
}
}
/**
* stop the thread
*/
public void shutdown() {
quit = true;
this.interrupt();
if (gpsdSocket != null) {
try {
gpsdSocket.close();
} catch (IOException ex) {
}
}
}
/**
* returns the current value of the local system time variable. Has a
* resolution of localTimeRenew ms.
*/
public static long getLocalSystemTime() {
TimeSync ts = getInstance();
if (ts.localTimeRenew == 0 || ts.localSysTime == 0) {
return System.currentTimeMillis();
} else {
return ts.localSysTime;
}
}
/**
* returns the current value of the local system time adjusted to global
* time. Has a resolution of localTimeRenew ms.
*/
public static long getGlobalTime() {
TimeSync ts = getInstance();
if (ts.localTimeRenew == 0 || ts.localSysTime == 0) {
return System.currentTimeMillis() + ts.currentDrift;
} else {
return ts.localSysTime + ts.currentDrift;
}
}
public static long getLocalRenewInterval() {
return getInstance().localTimeRenew;
}
public static int getTimeSyncInterval() {
return getInstance().timeSyncInterval;
}
public static int getSyncRTT() {
return getInstance().syncRTT;
}
public static boolean lastSyncWasSuccessful() {
return getInstance().syncSuccess;
}
/**
*
* @return the timestamp (local time) when the drift
* was successfully calculated
*/
public static long getLastSuccessfulSyncTimestamp() {
return getInstance().lastSuccessfulSync;
}
/**
* returns the current clock drift.
*/
public long getDrift() {
return this.currentDrift;
}
/**
* resynchronizes with the global time obtained from the DIR
*/
@SuppressWarnings("deprecation")
private void resync() {
switch (syncSource) {
case LOCAL_CLOCK : return;
case XTREEMFS_DIR : {
try {
long tStart = System.currentTimeMillis();
lastSyncAttempt = tStart;
long oldDrift = currentDrift;
long globalTime = timeServerClient.xtreemfs_global_time_get(null);
if (globalTime <= 0) {
//error
return;
}
long tEnd = System.currentTimeMillis();
// add half a roundtrip to estimate the delay
syncRTT = (int)(tEnd - tStart);
if (syncRTT > MAX_RTT) {
Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this,
"Ignored time synchronization message because DIR took too long to respond (%d ms)",
syncRTT);
syncSuccess = false;
return;
}
globalTime += syncRTT / 2;
syncSuccess = true;
currentDrift = globalTime - tEnd;
lastSuccessfulSync = tEnd;
if (Math.abs(oldDrift - currentDrift) > 5000 && oldDrift != 0) {
Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this,
"STRANGE DRIFT CHANGE from %d to %d", oldDrift, currentDrift);
}
} catch (Exception ex) {
syncSuccess = false;
ex.printStackTrace();
}
break;
}
case GPSD : {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream()));
OutputStream os = gpsdSocket.getOutputStream();
long tStart = System.currentTimeMillis();
lastSyncAttempt = tStart;
os.write(new byte[]{'d','\n'});
os.flush();
long oldDrift = currentDrift;
String response = br.readLine();
long tEnd = System.currentTimeMillis();
Matcher m = gpsdDatePattern.matcher(response);
Calendar c = Calendar.getInstance();
if (m.matches()) {
c.set(Calendar.YEAR, Integer.parseInt(m.group(1)));
c.set(Calendar.MONTH, Integer.parseInt(m.group(2))-1);
c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(3)));
c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4)));
c.set(Calendar.MINUTE, Integer.parseInt(m.group(5)));
c.set(Calendar.SECOND, Integer.parseInt(m.group(6)));
//c.set(Calendar.MILLISECOND, Integer.parseInt(m.group(7))*10);
} else {
Logging.logMessage(Logging.LEVEL_WARN, this,"cannot parse GPSd response: %s",response);
syncSuccess = false;
return;
}
long globalTime = c.getTimeInMillis();
Date d = new Date(globalTime);
Logging.logMessage(Logging.LEVEL_DEBUG, this,"global GPSd time: %d (%d:%d:%d)",c.getTimeInMillis(),d.getHours(),
d.getMinutes(),d.getSeconds());
// add half a roundtrip to estimate the delay
syncRTT = (int)(tEnd - tStart);
Logging.logMessage(Logging.LEVEL_DEBUG, this,"sync RTT: %d ms",syncRTT);
globalTime += syncRTT / 2;
syncSuccess = true;
currentDrift = globalTime - tEnd;
lastSuccessfulSync = tEnd;
Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this,
"resync success, drift: %d ms", Math.abs(oldDrift-currentDrift));
if (Math.abs(oldDrift - currentDrift) > 5000 && oldDrift != 0) {
Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this,
"STRANGE DRIFT CHANGE from %d to %d", oldDrift, currentDrift);
}
} catch (Exception ex) {
syncSuccess = false;
ex.printStackTrace();
}
}
}
}
public static TimeSync getInstance() {
if (theInstance == null)
throw new RuntimeException("TimeSync not initialized!");
return theInstance;
}
public static boolean isInitialized() {
return theInstance != null;
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation;
/**
* This class is meant to maintain version numbers for different components used
* in XtreemFS, in order to be able to detect possible incompatibilities between
* different versions.
*
* When a new version of the protocol, database, etc. has been implemented, the
* corresponding version number should be replaced. XtreemFS will rely on this
* class to find out what the current version numbers are.
*
*/
public class VersionManagement {
public static final String RELEASE_VERSION = "1.5.1 (Wonderful Waffles)";
private static final long mrcDataVersion = 10;
private static final long osdDataVersion = 1;
private static final long foundationVersion = 2;
public static long getMrcDataVersion() {
return mrcDataVersion;
}
public static long getOsdDataVersion() {
return osdDataVersion;
}
public static long getFoundationVersion() {
return foundationVersion;
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2010 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.buffer;
import java.io.Serializable;
/**
*
* @author bjko
*/
public final class ASCIIString implements Serializable {
private static final long serialVersionUID = 4633232360908659139L;
private byte[] data;
private int hash;
protected ASCIIString() {
}
/**
* Creates a new instance of ASCIIString
*/
public ASCIIString(String str) {
this.data = str.getBytes();
}
/**
* Creates a new instance of ASCIIString
*/
protected ASCIIString(byte[] data) {
this.data = data;
}
public String toString() {
return new String(data);
}
public char charAt(int index) {
return (char)data[index];
}
public boolean equals(Object o) {
if (o == null) return false;
try {
ASCIIString other = (ASCIIString)o;
if (other.length() != this.length())
return false;
for (int i = 0; i < data.length; i++) {
if (data[i] != other.data[i])
return false;
}
return true;
} catch (ClassCastException ex) {
return false;
}
}
public void marshall(ReusableBuffer target) {
target.putInt(data.length);
target.put(data);
}
public static ASCIIString unmarshall(ReusableBuffer target) {
int length = target.getInt();
if (length < 0)
return null;
byte[] tmp = new byte[length];
target.get(tmp);
return new ASCIIString(tmp);
}
public int hashCode() {
int h = hash;
if (h == 0) {
for (int i = 0; i < data.length; i++) {
h = 31*h + data[i];
}
hash = h;
}
return h;
}
public int length() {
return data.length;
}
public int getSerializedSize() {
return length()+Integer.SIZE/8;
}
}

View File

@@ -0,0 +1,324 @@
/*
* Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.buffer;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* A concurrent pool for buffer recycling.
*
* @author bjko
*/
public final class BufferPool {
/**
* size of buffers for each class.
*/
public static final int[] BUFF_SIZES = { 8192, 65536, 131072, 524288,
2097152 };
/**
* max pool size for each class
*/
public static final int[] MAX_POOL_SIZES = { 2000, 200, 100, 10, 5 };
/**
* queues to store buffers in
*/
private final ConcurrentLinkedQueue<ByteBuffer>[] pools;
/**
* pool sizes to avoid counting elements on each access
*/
private final AtomicInteger[] poolSizes;
/**
* stats for num requests and creates of buffers per class
*/
private final AtomicLong[] requests, creates, deletes;
/**
* singleton pattern.
*/
private static final BufferPool instance = new BufferPool();
/**
* if true all allocate/free operations record the stack trace. Useful to
* find memory leaks but slow.
*/
protected static boolean recordStackTraces = false;
/**
* Creates a new instance of BufferPool
*/
@SuppressWarnings("unchecked")
private BufferPool() {
pools = new ConcurrentLinkedQueue[BUFF_SIZES.length];
creates = new AtomicLong[BUFF_SIZES.length];
for (int i = 0; i < creates.length; i++) {
creates[i] = new AtomicLong();
}
requests = new AtomicLong[BUFF_SIZES.length + 1];
deletes = new AtomicLong[BUFF_SIZES.length + 1];
for (int i = 0; i < BUFF_SIZES.length + 1; i++) {
requests[i] = new AtomicLong();
deletes[i] = new AtomicLong();
}
poolSizes = new AtomicInteger[BUFF_SIZES.length];
for (int i = 0; i < BUFF_SIZES.length; i++) {
pools[i] = new ConcurrentLinkedQueue<ByteBuffer>();
poolSizes[i] = new AtomicInteger(0);
}
}
/**
* Get a new buffer. The Buffer is taken from the pool or created if none is
* available or the size exceedes the largest class.
*
* @param size
* the buffer's size in bytes
* @return a buffer of requested size
* @throws OutOfMemoryError
* if a buffer cannot be allocated
*/
public static ReusableBuffer allocate(int size) {
ReusableBuffer tmp = instance.getNewBuffer(size);
assert (tmp.refCount.get() == 1): "newly allocated buffer has invalid reference count: " + tmp.refCount.get();
if (recordStackTraces) {
tmp.allocStack = "\n";
for (StackTraceElement elem : new Exception().getStackTrace())
tmp.allocStack += elem.toString() + "\n";
}
return tmp;
}
/**
* Returns a buffer to the pool, if the buffer is reusable. Other buffers
* are ignored.
*
* @param buf
* the buffer to return
*/
public static void free(ReusableBuffer buf) {
if (buf != null) {
instance.returnBuffer(buf);
}
}
/**
* Returns a buffer which has at least size bytes.
*
* @attention The returned buffer can be larger than requested!
*/
private ReusableBuffer getNewBuffer(int size) {
try {
// if there is a pooled buffer with sufficient capacity ...
for (int i = 0; i < BUFF_SIZES.length; i++) {
if (size <= BUFF_SIZES[i]) {
ByteBuffer buf = pools[i].poll();
// if no free buffer is available in the pool ...
if (buf == null) {
// ... create
// - a direct buffer if the pool is not full yet,
// - a non-direct buffer if the pool is full
//
// Thus, the first MAX_POOL_SIZES[i] buffers will be
// pooled, whereas any additional buffers will be
// allocated on demand and freed by the garbage
// collector.
buf = creates[i].get() < MAX_POOL_SIZES[i] ? ByteBuffer.allocateDirect(BUFF_SIZES[i])
: ByteBuffer.allocate(BUFF_SIZES[i]);
creates[i].incrementAndGet();
}
// otherwise, decrement the pool size to indicate that the
// pooled buffer was handed out to the application
else {
poolSizes[i].decrementAndGet();
}
requests[i].incrementAndGet();
return new ReusableBuffer(buf, size);
}
}
// ... otherwise, create an unpooled buffer
requests[BUFF_SIZES.length].incrementAndGet();
ByteBuffer buf = ByteBuffer.allocate(size);
return new ReusableBuffer(buf, size);
} catch (OutOfMemoryError ex) {
System.out.println(getStatus());
throw ex;
}
}
private void returnBuffer(ReusableBuffer buffer) {
returnBuffer(buffer, false);
}
/**
* return a buffer to the pool
*/
private void returnBuffer(ReusableBuffer buffer, boolean callFromView) {
if (!buffer.isReusable())
return;
if (buffer.viewParent != null) {
// view buffer
if (recordStackTraces) {
if (buffer.freeStack == null)
buffer.freeStack = "";
buffer.freeStack += "\n";
StackTraceElement[] stackTrace = new Exception().getStackTrace();
for (int i = 0; i < stackTrace.length; i++)
buffer.freeStack += stackTrace[i].toString() + "\n";
}
assert (!buffer.returned) : "buffer was already released: " + buffer.freeStack;
buffer.returned = true;
returnBuffer(buffer.viewParent, true);
} else {
assert (!buffer.returned || callFromView) : "buffer was already released: " + buffer.freeStack;
if (recordStackTraces) {
if (buffer.freeStack == null)
buffer.freeStack = "";
buffer.freeStack += "\n";
StackTraceElement[] stackTrace = new Exception().getStackTrace();
for (int i = 0; i < stackTrace.length; i++)
buffer.freeStack += stackTrace[i].toString() + "\n";
}
if (!callFromView) {
buffer.returned = true;
}
if (buffer.refCount.getAndDecrement() > 1) {
return;
}
ByteBuffer buf = buffer.getParent();
buf.clear();
// determine the pool to which the buffer is supposed to be
// returned
// ...
for (int i = 0; i < BUFF_SIZES.length; i++) {
if (buf.capacity() == BUFF_SIZES[i]) {
// return direct buffers to the pool
if (buf.isDirect()) {
poolSizes[i].incrementAndGet();
pools[i].add(buf);
// since only direct buffers will be returned to the
// pool, which have been counted on allocation, there is
// no need to check the pool size here
return;
}
// if the buffer is non-direct, increment the delete counter
// and implicitly make the buffer subject to garbage
// collection
else {
deletes[i].incrementAndGet();
return;
}
}
}
assert (!buf.isDirect()) : "encountered direct buffer that does not fit in any of the pools (size="
+ buf.capacity() + "): " + buffer.freeStack;
// if the buffer did not fit in any of the pools,
// increment the delete counter for the unpooled buffers
deletes[deletes.length - 1].incrementAndGet();
}
}
/**
* Get the current pool size for a specific buffer size.
*
* @throws IllegalArgumentException
* when bufferSize is not in the pool
*/
public static int getPoolSize(int bufferSize) {
for (int i = 0; i < BUFF_SIZES.length; i++) {
if (BUFF_SIZES[i] == bufferSize) {
return instance.poolSizes[i].get();
}
}
throw new IllegalArgumentException("Specified buffer size is not pooled. Check BufferPool configuration.");
}
/**
* Returns a textual representation of the pool status.
*
* @return a textual representation of the pool status.
*/
public static String getStatus() {
String str = "";
for (int i = 0; i < BUFF_SIZES.length; i++) {
str += String.format(
"%8d: poolSize = %5d numRequests = %8d creates = %8d deletes = %8d\n",
BUFF_SIZES[i], instance.poolSizes[i].get(), instance.requests[i].get(), instance.creates[i]
.get(), instance.deletes[i].get());
}
str += String.format("unpooled (> %8d) numRequests = creates = %8d deletes = %8d",
BUFF_SIZES[BUFF_SIZES.length - 1], instance.requests[instance.requests.length - 1].get(),
instance.deletes[instance.deletes.length - 1].get());
return str;
}
/**
* Specifies whether stack traces shall be recorded when allocating and
* freeing buffers. Since recording stack traces leads to some overhead, it
* should only be enabled for debugging purposes.
*
* @param record
*/
public static void enableStackTraceRecording(boolean record) {
recordStackTraces = record;
}
}

View File

@@ -0,0 +1,724 @@
/*
* Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.buffer;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.concurrent.atomic.AtomicInteger;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;
/**
*
* @author bjko
*/
public final class ReusableBuffer {
private static final Charset ENC_UTF8 = Charset.forName("utf-8");
/**
* A view buffer of parentBuffer with the requested size. For non-reusable
* buffers this is the buffer itself
*/
private ByteBuffer buffer;
/**
* A parent buffer which is returned to the pool
*/
private final ByteBuffer parentBuffer;
/**
* True if the buffer can be returned to the pool
*/
private final boolean reusable;
/**
* set to true after a buffer was returned to the pool
*/
protected volatile boolean returned;
/**
* size (as requested), might be smaller than parentBuffer size but is
* always equal to the (view) buffer size.
*/
private int size;
protected ReusableBuffer viewParent;
protected String freeStack, allocStack;
/**
* reference count
*/
AtomicInteger refCount;
/**
* Creates a new instance of ReusableBuffer. A view buffer of size is created.
*
* @param buffer
* the parent buffer
* @param size
* the requested size
*/
protected ReusableBuffer(ByteBuffer buffer, int size) {
buffer.position(0);
buffer.limit(size);
this.buffer = buffer.slice();
this.parentBuffer = buffer;
this.size = size;
this.reusable = true;
this.refCount = new AtomicInteger(1);
returned = false;
viewParent = null;
}
/**
* A wrapper for a non-reusable buffer. The buffer is not used by the pool
* when returned.
*/
public ReusableBuffer(ByteBuffer nonManaged) {
this.buffer = nonManaged;
this.size = buffer.limit();
this.reusable = false;
this.parentBuffer = null;
returned = false;
this.refCount = new AtomicInteger(1);
viewParent = null;
}
/**
* Creates a non-reusable buffer around a byte array. Uses the
* ByteBuffer.wrap method.
*
* @param data
* the byte arry containing the data
* @return
*/
public static ReusableBuffer wrap(byte[] data) {
return new ReusableBuffer(ByteBuffer.wrap(data));
}
public static ReusableBuffer wrap(byte[] data, int offset, int length) {
assert (offset >= 0);
assert (length >= 0);
if (offset + length > data.length)
throw new IllegalArgumentException("offset+length > buffer size (" + offset + "+" + length
+ " > " + data.length);
ByteBuffer tmp = ByteBuffer.wrap(data);
tmp.position(offset);
tmp.limit(offset + length);
return new ReusableBuffer(tmp.slice());
}
/**
* Creates a new view buffer. This view buffer shares the same data (i.e.
* backing byte buffer) but has independent position, limit etc.
*/
public ReusableBuffer createViewBuffer() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
if (this.viewParent == null) {
if (parentBuffer == null) {
// wraped buffers
ReusableBuffer view = new ReusableBuffer(this.buffer.slice());
view.viewParent = this;
return view;
} else {
// regular buffer
ReusableBuffer view = new ReusableBuffer(this.parentBuffer, this.size);
view.viewParent = this;
this.refCount.incrementAndGet();
if (BufferPool.recordStackTraces) {
view.allocStack = "\n";
StackTraceElement[] stackTrace = new Exception().getStackTrace();
for (int i = 0; i < stackTrace.length; i++)
view.allocStack += stackTrace[i].toString() + (i < stackTrace.length - 1 ? "\n" : "");
}
return view;
}
} else {
if (parentBuffer == null) {
// wraped buffers
ReusableBuffer view = new ReusableBuffer(this.buffer.slice());
view.viewParent = this.viewParent;
return view;
} else {
// regular buffer: use the parent to create a view buffer
ReusableBuffer view = new ReusableBuffer(this.buffer, this.size);
view.viewParent = this.viewParent;
this.viewParent.refCount.incrementAndGet();
if (BufferPool.recordStackTraces) {
view.allocStack = "\n";
StackTraceElement[] stackTrace = new Exception().getStackTrace();
for (int i = 0; i < stackTrace.length; i++)
view.allocStack += stackTrace[i].toString() + (i < stackTrace.length - 1 ? "\n" : "");
}
return view;
}
}
}
/**
* @see java.nio.Buffer#capacity
*/
public int capacity() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return this.size;
}
/**
* May be higher than {@link #capacity()} if the parent buffer is from the {@link BufferPool} which may
* have returned a larger buffer.
*/
public int capacityUnderlying() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return parentBuffer != null ? parentBuffer.capacity() : this.size;
}
/**
* @see java.nio.ByteBuffer#hasArray
*/
public boolean hasArray() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.hasArray();
}
/**
* Returns the byte array of the buffer, creating a copy if the buffer is
* not backed by an array
*
* @return a byte array with a copy of the data
*/
public byte[] array() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
byte[] array = null;
if (this.hasArray() && (this.viewParent == null)) {
array = buffer.array();
} else {
array = new byte[this.limit()];
final int oldPos = this.position();
this.position(0);
this.get(array);
this.position(oldPos);
}
return array;
}
/**
* @see java.nio.Buffer#flip
*/
public void flip() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.flip();
}
/**
* @see java.nio.Buffer#compact
*/
public void compact() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.compact();
}
/**
* @see java.nio.Buffer#limit(int)
*/
public void limit(int l) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.limit(l);
}
/**
* @see java.nio.Buffer#limit()
*/
public int limit() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.limit();
}
/**
* @see java.nio.Buffer#position(int)
*/
public void position(int p) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.position(p);
}
/**
* @see java.nio.Buffer#position()
*/
public int position() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.position();
}
/**
* @see java.nio.Buffer#hasRemaining
*/
public boolean hasRemaining() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.hasRemaining();
}
/**
* Returns the view buffer encapsulated by this ReusableBuffer.
*
* @return the view buffer
*/
public ByteBuffer getBuffer() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return this.buffer;
}
/**
* Returns true, if this buffer is re-usable and can be returned to the
* pool.
*
* @return true, if this buffer is re-usable
*/
public boolean isReusable() {
// assert(!returned) :
// "Buffer was already freed and cannot be used anymore"+this.freeStack;
return this.reusable;
}
/**
* Returns the parent buffer.
*
* @return the parent buffer
*/
protected ByteBuffer getParent() {
return this.parentBuffer;
}
/**
* @see java.nio.ByteBuffer#get()
*/
public byte get() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.get();
}
public byte get(int index) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.get(index);
}
/**
* @see java.nio.ByteBuffer#get(byte[])
*/
public ReusableBuffer get(byte[] dst) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.get(dst);
return this;
}
/**
* @see java.nio.ByteBuffer#get(byte[], int offset, int length)
*/
public ReusableBuffer get(byte[] dst, int offset, int length) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.get(dst, offset, length);
return this;
}
/**
* @see java.nio.ByteBuffer#put(byte)
*/
public ReusableBuffer put(byte b) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.put(b);
return this;
}
/**
* @see java.nio.ByteBuffer#put(byte[])
*/
public ReusableBuffer put(byte[] src) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.put(src);
return this;
}
/**
* @see java.nio.ByteBuffer#put(byte[],int,int)
*/
public ReusableBuffer put(byte[] src, int offset, int len) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.put(src, offset, len);
return this;
}
/**
* @see java.nio.ByteBuffer#put(ByteBuffer)
*/
public ReusableBuffer put(ByteBuffer src) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.put(src);
return this;
}
/**
* Writes the content of src into this buffer.
*
* @param src
* the buffer to read from
* @return this ReusableBuffer after reading
* @see java.nio.ByteBuffer#put(ByteBuffer)
*/
public ReusableBuffer put(ReusableBuffer src) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.put(src.buffer);
return this;
}
/**
* @see java.nio.ByteBuffer#getInt
*/
public int getInt() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.getInt();
}
/**
* @see java.nio.ByteBuffer#putInt(int)
*/
public ReusableBuffer putInt(int i) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.putInt(i);
return this;
}
public long getLong() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.getLong();
}
public ReusableBuffer putLong(long l) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.putLong(l);
return this;
}
public double getDouble() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.getDouble();
}
public ReusableBuffer putDouble(double d) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.putDouble(d);
return this;
}
public String getString() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
int length = buffer.getInt();
if (length > 0) {
byte[] bytes = new byte[length];
buffer.get(bytes);
return new String(bytes, ENC_UTF8);
} else if (length == 0) {
return "";
} else {
return null;
}
}
public ReusableBuffer putString(String str) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
if (str != null) {
byte[] bytes = str.getBytes(ENC_UTF8);
buffer.putInt(bytes.length);
buffer.put(bytes);
} else {
buffer.putInt(-1);
}
return this;
}
public ReusableBuffer putShortString(String str) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
assert (str.length() <= Short.MAX_VALUE);
if (str != null) {
byte[] bytes = str.getBytes(ENC_UTF8);
buffer.putShort((short) bytes.length);
buffer.put(bytes);
} else {
buffer.putInt(-1);
}
return this;
}
public ASCIIString getBufferBackedASCIIString() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return ASCIIString.unmarshall(this);
}
public ReusableBuffer putBufferBackedASCIIString(ASCIIString str) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
if (str != null) {
str.marshall(this);
} else {
buffer.putInt(-1);
}
return this;
}
public ReusableBuffer putShort(short s) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.putShort(s);
return this;
}
public short getShort() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.getShort();
}
/**
* @see java.nio.ByteBuffer#isDirect
*/
public boolean isDirect() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.isDirect();
}
/**
* @see java.nio.Buffer#remaining
*/
public int remaining() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.remaining();
}
/**
* @see java.nio.Buffer#clear
*/
public void clear() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.clear();
}
public byte[] getData() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
byte[] array = new byte[this.limit()];
this.position(0);
this.get(array);
return array;
}
public void shrink(int newSize) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
if (newSize > size) {
throw new IllegalArgumentException("new size must not be larger than old size");
}
this.size = newSize;
int oldPos = buffer.position();
if (oldPos > newSize)
oldPos = 0;
// save parent position and limit
ByteBuffer originalBuffer;
if (parentBuffer != null) {
originalBuffer = parentBuffer;
} else {
originalBuffer = buffer;
}
int position = originalBuffer.position();
int limit = originalBuffer.limit();
originalBuffer.position(0);
originalBuffer.limit(newSize);
this.buffer = originalBuffer.slice();
buffer.position(oldPos);
// restore parent position and limit
originalBuffer.position(position);
originalBuffer.limit(limit);
}
/*
* Increases the capacity of this buffer. Returns false if {@code newSize} is bigger than the capacity of
* the underlying buffer.
*
* The underlying buffer can be a reusable buffer (parentBuffer != 0) or non-reusable buffer (viewParent
* != 0).
*/
public boolean enlarge(int newSize) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
if (newSize == this.size) {
return true;
}
if (parentBuffer == null && viewParent == null) {
return false;
}
ByteBuffer underlyingBuffer = parentBuffer != null ? parentBuffer : viewParent.getBuffer();
if (newSize > underlyingBuffer.capacity()) {
return false;
} else {
this.size = newSize;
int oldPos = buffer.position();
if (oldPos > newSize)
oldPos = 0;
// save parent position and limit
int position = underlyingBuffer.position();
int limit = underlyingBuffer.limit();
underlyingBuffer.position(0);
underlyingBuffer.limit(newSize);
this.buffer = underlyingBuffer.slice();
buffer.position(oldPos);
// restore parent position and limit
underlyingBuffer.position(position);
underlyingBuffer.limit(limit);
return true;
}
}
/*
* Sets the new range of the buffer starting from {@code offset} going for {@code length} bytes.
*
* The new position of the buffer will be 0 and the size/capacity will equal {@code length}.
*/
public void range(int offset, int length) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
// useless call!
if ((offset == 0) && (length == this.size))
return;
if (offset >= size) {
throw new IllegalArgumentException("offset must be < size. offset=" + offset + " size=" + size);
}
if (offset + length > size) {
throw new IllegalArgumentException("offset+length must be <= size. size=" + size + " offset="
+ offset + " length=" + length);
}
this.size = length;
// save parent position and limit
ByteBuffer originalBuffer;
if (parentBuffer != null) {
originalBuffer = parentBuffer;
} else {
originalBuffer = buffer;
}
int position = originalBuffer.position();
int limit = originalBuffer.limit();
// ensure that the subsequent 'position' does not fail
if (offset > limit)
originalBuffer.limit(offset);
originalBuffer.position(offset);
originalBuffer.limit(offset + length);
this.buffer = originalBuffer.slice();
assert (this.buffer.capacity() == length);
// restore parent position and limit
originalBuffer.position(position);
originalBuffer.limit(limit);
}
public ReusableBuffer putBoolean(boolean bool) {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
buffer.put(bool ? (byte) 1 : (byte) 0);
return this;
}
public boolean getBoolean() {
assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack;
return buffer.get() == 1;
}
public int getRefCount() {
if (this.viewParent == null) {
return this.refCount.get();
} else {
return this.viewParent.refCount.get();
}
}
@Override
protected void finalize() {
if (!returned && reusable) {
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this,
"buffer was finalized but not freed before! buffer = %s, refCount=%d", this.toString(), getRefCount());
if (allocStack != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "stacktrace: %s", allocStack);
if (this.viewParent != null)
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "parent stacktrace: %s",
viewParent.allocStack);
}
if (freeStack != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "freed at: %s", freeStack);
} else if (viewParent != null && viewParent.freeStack != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "freed at: %s", viewParent.freeStack);
}
if (Logging.isDebug()) {
byte[] data = new byte[(this.capacity() > 128) ? 128 : this.capacity()];
this.position(0);
this.limit(this.capacity());
this.get(data);
String content = new String(data);
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "content: %s", content);
if (this.viewParent != null) {
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "view parent: %s",
this.viewParent.toString());
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "ref count: %d",
this.viewParent.refCount.get());
} else {
Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "ref count: %d",
this.refCount.get());
}
}
BufferPool.free(this);
}
}
@Override
public String toString() {
return "ReusableBuffer( capacity=" + this.capacity() + " limit=" + this.limit() + " position="
+ this.position() + ")";
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums;
import java.nio.ByteBuffer;
/**
* An interface which must be implemented by checksum algorithms for XtreemFS.
*
* 19.08.2008
*
* @author clorenz
*/
public interface ChecksumAlgorithm extends Cloneable {
/**
* Returns a string that identifies the algorithm, independent of
* implementation details.
*
* @return name of algorithm
*/
public String getName();
/**
* Returns checksum value (as Hex-String) and resets the Algorithm.
*
* @return checksum
*/
public long getValue();
/**
* Resets checksum to initial value.
*
* @return
*/
public void reset();
/**
* Updates checksum with specified data.
*
* @param data
*/
public void update(ByteBuffer data);
/**
* returns a new instance of the checksum algorithm
*
* @return
*/
public ChecksumAlgorithm clone();
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* A Factory for getting checksum algorithms from checksum provider. Implemented
* as a Singleton.
*
* 19.08.2008
*
* @author clorenz
*/
public class ChecksumFactory {
/**
* amount of cached instances/algorithm
*/
private static int MAX_CACHE_SIZE = 20;
private static ChecksumFactory self;
/**
* Contains all available checksum algorithms (only one instance).
*/
private HashMap<String, ChecksumAlgorithm> algorithms;
/**
* Contains all known checksum provider
*/
private HashMap<String, ChecksumProvider> knownProvider;
/**
* Contains cached instances for all available checksum algorithms.
*/
private HashMap<String, ConcurrentLinkedQueue<ChecksumAlgorithm>> pool;
/**
* creates a new ChecksumFactory
*/
private ChecksumFactory() {
super();
this.algorithms = new HashMap<String, ChecksumAlgorithm>();
this.pool = new HashMap<String, ConcurrentLinkedQueue<ChecksumAlgorithm>>();
this.knownProvider = new HashMap<String, ChecksumProvider>();
}
/**
* Get the instance of ChecksumFactory.
*
* @return the instance
*/
public static ChecksumFactory getInstance() {
if (self == null) {
self = new ChecksumFactory();
}
return self;
}
/**
* Get an instance of a specific checksum algorithm, if supported.
*
* @param name
* of the algorithm
* @return algorithm object or null, if algorithm is not supported
*/
public ChecksumAlgorithm getAlgorithm(String name)
throws NoSuchAlgorithmException {
ConcurrentLinkedQueue<ChecksumAlgorithm> cache = pool.get(name);
if (cache == null)
throw new NoSuchAlgorithmException("algorithm " + name
+ " not supported");
ChecksumAlgorithm algorithm = cache.poll();
if (algorithm == null) { // cache is empty
return algorithms.get(name).clone(); // create new instance
} else {
return algorithm; // return caches instance
}
}
/**
* Returns an instance of a specific checksum algorithm for caching.
*
* @param instance
* of the algorithm
*/
public void returnAlgorithm(ChecksumAlgorithm algorithm) {
ConcurrentLinkedQueue<ChecksumAlgorithm> cache = pool.get(algorithm
.getName());
if (cache.size() < MAX_CACHE_SIZE) {
algorithm.reset();
cache.add(algorithm);
}
}
/**
* Adds a new provider to factory and adds all supported algorithms from the
* provider to the algorithms-list. NOTE: Existing algorithms will be
* overridden when the new provider contains the same algorithm (maybe
* another implementation).
*
* @param provider
*/
public void addProvider(ChecksumProvider provider) {
knownProvider.put(provider.getName(), provider);
for (ChecksumAlgorithm algorithm : provider.getSupportedAlgorithms()) {
addAlgorithm(algorithm);
}
}
/**
* Adds a new Algorithm to factory. NOTE: The same existing algorithm will
* be overridden.
*
* @param algorithm
*/
public void addAlgorithm(ChecksumAlgorithm algorithm) {
algorithms.put(algorithm.getName(), algorithm);
pool.put(algorithm.getName(),
new ConcurrentLinkedQueue<ChecksumAlgorithm>());
}
/**
* Removes a provider, but not the added algorithms.
*
* @param provider
*/
public void removeProvider(ChecksumProvider provider) {
knownProvider.remove(provider.getName());
}
/**
* Removes an algorithm.
*
* @param algorithm
*/
public void removeAlgorithm(String algorithm) {
algorithms.remove(algorithm);
pool.remove(algorithm);
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums;
import java.util.Collection;
import java.util.HashMap;
/**
* An abstract class which must be implemented by a checksum provider for
* XtreemFS.
*
* 19.08.2008
*
* @author clorenz
*/
public abstract class ChecksumProvider {
/**
* contains the supported algorithms
*/
protected HashMap<String, ChecksumAlgorithm> algorithms;
protected ChecksumProvider() {
super();
this.algorithms = new HashMap<String, ChecksumAlgorithm>();
}
/**
* Returns the name of the provider.
*
* @return name
*/
public abstract String getName();
/**
* Returns all from this provider supported checksum algorithms.
*
* @return a collection with ChecksumAlgorithms
*/
public Collection<ChecksumAlgorithm> getSupportedAlgorithms() {
return algorithms.values();
}
/**
* adds an algorithm to the map
*
* @param newAlgorithm
*/
protected void addAlgorithm(ChecksumAlgorithm newAlgorithm) {
this.algorithms.put(newAlgorithm.getName(), newAlgorithm);
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums;
/**
* An interface for checksum algorithms, which are based on computations on
* strings.
*
* 02.09.2008
*
* @author clorenz
*/
public interface StringChecksumAlgorithm extends ChecksumAlgorithm {
/**
* Updates checksum with specified data.
*
* @param data
*/
public void digest(String data);
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums.algorithms;
/**
* The Adler32 algorithm. It uses the Java internal implementation.
*
* 19.08.2008
*
* @author clorenz
*/
@SuppressWarnings("unchecked")
public class Adler32 extends JavaChecksumAlgorithm {
public Adler32() {
super(new java.util.zip.Adler32(), "Adler32");
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone()
*/
@Override
public Adler32 clone() {
return new Adler32();
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums.algorithms;
/**
* The CRC32 algorithm. It uses the Java internal implementation.
*
* 19.08.2008
*
* @author clorenz
*/
@SuppressWarnings("unchecked")
public class CRC32 extends JavaChecksumAlgorithm {
public CRC32() {
super(new java.util.zip.CRC32(), "CRC32");
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone()
*/
@Override
public CRC32 clone() {
return new CRC32();
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums.algorithms;
import java.nio.ByteBuffer;
import java.util.zip.Checksum;
import org.xtreemfs.foundation.checksums.ChecksumAlgorithm;
/**
* An abstract wrapper for Java internal checksums.
*
* 19.08.2008
*
* @author clorenz
*/
abstract public class JavaChecksumAlgorithm<RealJavaAlgorithm extends Checksum>
implements ChecksumAlgorithm {
/**
* the class, which really implements the selected algorithm
*/
protected RealJavaAlgorithm realAlgorithm;
protected String name;
public JavaChecksumAlgorithm(RealJavaAlgorithm realAlgorithm, String name) {
super();
this.realAlgorithm = realAlgorithm;
this.name = name;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#digest(java.nio.ByteBuffer)
*/
@Override
public void update(ByteBuffer data) {
byte[] array;
if (data.hasArray()) {
array = data.array();
} else {
array = new byte[data.capacity()];
final int oldPos = data.position();
data.position(0);
data.get(array);
data.position(oldPos);
}
realAlgorithm.update(array, 0, array.length);
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#getName()
*/
@Override
public String getName() {
return name;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#getValue()
*/
@Override
public long getValue() {
final long tmp = realAlgorithm.getValue();
realAlgorithm.reset();
return tmp;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#reset()
*/
@Override
public void reset() {
realAlgorithm.reset();
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone()
*/
@Override
public abstract JavaChecksumAlgorithm<?> clone();
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums.algorithms;
import java.nio.ByteBuffer;
import org.xtreemfs.foundation.checksums.StringChecksumAlgorithm;
/**
* The Java algorithm, which is used for string.hashCode(). It uses the Java
* internal implementation.
*
* 02.09.2008
*
* @author clorenz
*/
public class JavaHash implements StringChecksumAlgorithm {
private Long hash = null;
private String name = "Java-Hash";
/**
* Updates checksum with specified data.
*
* @param data
*/
public void digest(String data) {
this.hash = Long.valueOf(data.hashCode());
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#digest(java.nio.ByteBuffer)
*/
@Override
public void update(ByteBuffer data) {
byte[] array;
if (data.hasArray()) {
array = data.array();
} else {
array = new byte[data.capacity()];
final int oldPos = data.position();
data.position(0);
data.get(array);
data.position(oldPos);
}
this.hash = (long)new String(array).hashCode();
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getName()
*/
@Override
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getValue()
*/
@Override
public long getValue() {
long value;
if (this.hash != null)
value = this.hash;
else
value = 0;
reset();
return value;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#reset()
*/
@Override
public void reset() {
hash = null;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone()
*/
@Override
public JavaHash clone() {
return new JavaHash();
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums.algorithms;
import java.nio.ByteBuffer;
import org.xtreemfs.foundation.checksums.StringChecksumAlgorithm;
/**
* The SDBM algorithm.
*
* 02.09.2008
*
* @author clorenz
*/
public class SDBM implements StringChecksumAlgorithm {
private Long hash = null;
private String name = "SDBM";
/**
* Updates checksum with specified data.
*
* @param data
*/
public void digest(String data) {
this.hash = sdbmHash(data);
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#digest(java.nio.ByteBuffer)
*/
@Override
public void update(ByteBuffer data) {
byte[] array;
if (data.hasArray()) {
array = data.array();
} else {
array = new byte[data.capacity()];
final int oldPos = data.position();
data.position(0);
data.get(array);
data.position(oldPos);
}
this.hash = sdbmHash(new String(array));
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getName()
*/
@Override
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getValue()
*/
@Override
public long getValue() {
long value;
if (this.hash != null)
value = this.hash;
else
value = 0;
reset();
return value;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#reset()
*/
@Override
public void reset() {
hash = null;
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone()
*/
@Override
public SDBM clone() {
return new SDBM();
}
/**
* SDBM algorithm
*
* @param str
* @return
*/
protected static long sdbmHash(String str) {
long hash = 0;
for (int c : str.toCharArray()) {
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2008-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.checksums.provider;
import org.xtreemfs.foundation.checksums.ChecksumProvider;
/**
* A provider for Java internal checksums. offers the following algorithms:
* Adler32, CRC32, MD5, Java-Hash
*
* 19.08.2008
*
* @author clorenz
*/
public class JavaChecksumProvider extends ChecksumProvider {
private static String NAME = "Java Checksum Provider";
/**
* creates a new JavaChecksumProvider
*/
public JavaChecksumProvider() {
super();
addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.Adler32());
addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.CRC32());
/*try {
addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.JavaMessageDigestAlgorithm(
"MD5", "MD5"));
addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.JavaMessageDigestAlgorithm(
"SHA1", "SHA-1"));
} catch (NoSuchAlgorithmException e) {
Logging.logMessage(Logging.LEVEL_WARN, this, e.getMessage()
+ " in your java-installation");
}*/
addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.JavaHash());
}
/*
* (non-Javadoc)
*
* @see org.xtreemfs.foundation.checksums.ChecksumProvider#getName()
*/
@Override
public String getName() {
return NAME;
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.json;
import java.nio.BufferUnderflowException;
import java.nio.CharBuffer;
/**
*
* @author bjko
*/
public class JSONCharBufferString implements JSONInput {
CharBuffer cb;
/** Creates a new instance of JSONCharBufferString */
public JSONCharBufferString(CharBuffer cb) {
assert (cb != null);
this.cb = cb;
this.cb.position(0);
}
public char read() throws JSONException {
try {
return cb.get();
} catch(BufferUnderflowException ex) {
throw new JSONException("Reached end of buffer");
}
}
public int skip(int skip) {
try {
cb.position(cb.position()+skip);
return skip;
} catch (IllegalArgumentException e) {
return 0;
}
}
public String toString() {
return "JSONCharBufferString backed by "+cb.toString();
}
public boolean hasMore() {
return cb.hasRemaining();
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.json;
/**
* Thrown by the JSON parser and writer.
*
* @author bjko
*/
public class JSONException extends java.lang.Exception {
/***/
private static final long serialVersionUID = 2422241603599209392L;
/**
* Creates a new instance of <code>JSONException</code> without detail
* message.
*/
public JSONException() {
}
/**
* Constructs an instance of <code>JSONException</code> with the specified
* detail message.
*
* @param msg
* the detail message.
*/
public JSONException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.json;
/**
*
* @author bjko
*/
public interface JSONInput {
/**
* reads a single char
*
* @return the character at the current position is returned
*/
public char read() throws JSONException;
/**
* It checks if there are more characters
*/
public boolean hasMore();
/**
* Skips skip characters
*
* @param skip
* num characters to skip
* @return the number of characters skipped
*/
public int skip(int skip);
/**
* Get a string representation.
*
* @return A string representation of the this JSONString.
*/
public String toString();
}

View File

@@ -0,0 +1,329 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.json;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* JSON Parser routines. This parser accepts any value as top level element, not
* just an object or array.
*
* @author bjko
*/
public class JSONParser {
/**
* Creates a new instance of JSONParser
*/
public JSONParser() {
}
private static String parseString(JSONInput input) throws JSONException {
boolean nonEscaped = true;
StringBuilder str = new StringBuilder();
while (input.hasMore()) {
char ch = input.read();
if (nonEscaped) {
if (ch == '\\') {
nonEscaped = false;
continue;
}
else if (ch == '"') {
return str.toString();
}
else {
str.append(ch);
}
}
else {
if (ch == 'n') {
str.append('\n');
} else if (ch == 'r') {
str.append('\r');
} else if (ch == 't') {
str.append('\t');
} else {
str.append(ch);
}
}
nonEscaped = true;
}
throw new JSONException("[ E | JSONParser ] Unexpected end while parsing string");
}
private static Object parseNumber(JSONInput input) throws JSONException {
StringBuilder str = new StringBuilder();
input.skip(-1);
boolean isFP = false;
while (input.hasMore()) {
char ch = input.read();
if ((ch == '-') || (ch >= '0') && (ch <= '9')) {
str.append(ch);
} else if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
str.append(ch);
isFP = true;
} else {
input.skip(-1);
if (isFP)
return new BigDecimal(str.toString());
else
return Long.valueOf(str.toString());
}
}
if (isFP)
return new BigDecimal(str.toString());
else
return Long.valueOf(str.toString());
}
private static Object parseArray(JSONInput input) throws JSONException {
LinkedList<Object> arr = new LinkedList<Object>();
while (input.hasMore()) {
char ch = input.read();
if (ch == ']') {
return arr;
} else if (ch == ',') {
arr.add(parseJSON(input));
} else if ((ch == ' ') || (ch == '\t')) {
continue;
} else {
input.skip(-1);
arr.add(parseJSON(input));
}
}
throw new JSONException("[ E | JSONParser ] Unexpected end while parsing array");
}
private static Object parseObject(JSONInput input) throws JSONException {
HashMap<String, Object> map = new HashMap<String, Object>();
while (input.hasMore()) {
char ch = input.read();
if (ch == '}') {
return map;
}
// skip all ws
if ((ch == ' ') || (ch == '\t')) {
continue;
}
String name = parseString(input);
ch = input.read();
while ((ch == ' ') || (ch == '\t')) {
ch = input.read();
}
if (ch != ':') {
throw new JSONException("[ E | JSONParser ] Unexpected token '"
+ ((char) ch) + "' or EOF. Expected : in Object.");
}
while ((ch == ' ') || (ch == '\t')) {
ch = input.read();
}
Object value = parseJSON(input);
map.put(name, value);
ch = input.read();
while ((ch == ' ') || (ch == '\t')) {
ch = input.read();
}
if (ch == '}') {
return map;
}
if (ch != ',') {
throw new JSONException("[ E | JSONParser ] Unexpected token '"
+ ((char) ch) + "' or EOF. Expected , or } in Object.");
}
}
throw new JSONException("[ E | JSONParser ] Unexpected end while parsing object");
}
/**
* Parses a JSON message.
*
* @return the objects encoded in input.
* @attention This routine may cause a StackOverflow exception when parsing
* incorrect, very deep or maliciously malformed JSON messages.
* @param input
* the JSON string
* @throws org.xtreemos.wp34.mrc.utils.JSONException
* if input is not valid JSON
*/
public static Object parseJSON(JSONInput input) throws JSONException {
while (input.hasMore()) {
char ch = input.read();
if (ch == '[') {
return parseArray(input);
} else if (ch == '{') {
return parseObject(input);
} else if (ch == '"') {
return parseString(input);
} else if ((ch == '-') || ((ch >= '0') && (ch <= '9'))) {
return parseNumber(input);
} else if (ch == 't') {
input.skip(3);
return Boolean.valueOf(true);
} else if (ch == 'f') {
input.skip(4);
return Boolean.valueOf(false);
} else if (ch == 'n') {
input.skip(3);
return null;
} else if ((ch == ' ') || (ch == '\t')) {
continue;
} else {
throw new JSONException("[ E | JSONParser ] Unexpected token '"
+ ((char) ch) + "' expected Object, Array or Value.");
}
}
throw new JSONException("[ E | JSONParser ] Unexpected end while parsing root element");
}
/**
* Creates a JSON encoded message from an object. Can handle Boolean,
* Integer, Long, BigDecimal, List and Map.
*
* @param input
* object to encode, objects can be nested.
* @return a JSON encoded message
* @throws org.xtreemos.wp34.mrc.utils.JSONException
* if there are one or more objects it cannot encode
*/
public static String writeJSON(Object input) throws JSONException {
return writeJSON(input,new StringBuilder()).toString();
}
/**
* Creates a JSON encoded message from an object. Can handle Boolean,
* Integer, Long, BigDecimal, List and Map.
*
* @param input
* object to encode, objects can be nested.
* @return a JSON encoded message
* @throws org.xtreemos.wp34.mrc.utils.JSONException
* if there are one or more objects it cannot encode
*/
@SuppressWarnings("unchecked")
public static StringBuilder writeJSON(Object input, StringBuilder result) throws JSONException {
if (input == null) {
return result.append("null");
} else if (input instanceof Boolean) {
return result.append(((Boolean) input).booleanValue() ? "true" : "false");
} else if (input instanceof BigDecimal) {
return result.append(((BigDecimal) input).toString());
} else if (input instanceof Integer) {
return result.append((Integer) input);
} else if (input instanceof Long) {
return result.append((Long) input);
} else if (input instanceof String) {
return writeJSONString(input,result);
} else if (input instanceof Map) {
return writeJSONObject(input,result);
} else if (input instanceof Collection) {
return writeJSONArray(input,result);
} else {
throw new JSONException(
"[ E | JSONParser ] Unexpected Object type: "
+ input.getClass().getName());
}
}
@SuppressWarnings("unchecked")
private static StringBuilder writeJSONObject(Object input, StringBuilder result) throws JSONException {
Map<Object, Object> map = (Map) input;
result.append("{");
int i = 1;
for (Object key : map.keySet()) {
writeJSONString(key.toString(),result);
result.append(":");
writeJSON(map.get(key),result);
if (i < map.size())
result.append(",");
i++;
}
return result.append("}");
}
@SuppressWarnings("unchecked")
private static StringBuilder writeJSONArray(Object input, StringBuilder result) throws JSONException {
Collection<Object> arr = (Collection<Object>) input;
result.append("[");
int i = 1;
for (Object obj : arr) {
writeJSON(obj,result);
if (i < arr.size())
result.append(",");
i++;
}
return result.append("]");
}
private static StringBuilder writeJSONString(Object input, StringBuilder result) {
/*
* This is 10 times faster than using str.replace
*/
final String str = input.toString();
result.append("\"");
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
switch (ch) {
case '\n' : result.append("\\n"); break;
case '\r' : result.append("\\r"); break;
case '\t' : result.append("\\t"); break;
case '"' : result.append("\\\""); break;
case '\\' : result.append("\\\\"); break;
case '/' : result.append("\\/"); break;
default: result.append(ch);
}
}
result.append("\"");
return result;
}
public static String toJSON(Object... args) throws JSONException {
List<Object> argList = new ArrayList<Object>(args.length);
for (Object arg : args)
argList.add(arg);
return writeJSON(argList);
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.json;
/**
* This class is necessary because the StringReader cannot skip back once the
* end is reached.
*
* @author bjko
*/
public class JSONString implements JSONInput {
String str;
int position;
/**
* Creates a new instance of JSONString
*
* @param str
* the JSON message
*/
public JSONString(String str) {
this.str = str;
position = 0;
}
/**
* reads a single char
*
* @return the character at the current position is returned
*/
public char read() throws JSONException {
try {
return str.charAt(position++);
}
catch (StringIndexOutOfBoundsException ex) {
throw new JSONException("Reach the end of the string");
}
}
/**
*/
public boolean hasMore() {
return position < str.length();
}
/**
* Skips skip characters
*
* @param skip
* num characters to skip
* @return the number of characters skipped
*/
public int skip(int skip) {
if (((position + skip) < 0) || ((position + skip) >= str.length())) {
return 0;
} else {
position = position + skip;
return skip;
}
}
/**
* Get a string representation.
*
* @return A string representation of the this JSONString.
*/
public String toString() {
return "JSONString pos=" + position + " str=" + str;
}
}

View File

@@ -0,0 +1,274 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.logging;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* @author bjko
*/
public class Logging {
public enum Category {
/**
* enable logging for all categories (no real category)
*/
all,
/**
* logs messages pertaining to buffers
*/
buffer,
/**
* log messaages pertaining to service lifecycles (threads)
*/
lifecycle,
/**
* network-related log messages
*/
net,
/**
* authorization-related log messages
*/
auth,
/**
* log messages pertaining to the request flow through the stages
*/
stage,
/**
* log messages pertaining to any kind of request processing
*/
proc,
/**
*
*/
misc,
/**
* log messages pertaining storage on OSD or database access on MRC/DIR
*/
storage,
/**
* logs messages pertaining to replication
*/
replication,
/**
* logs messages from additional tools
*/
tool,
/**
* logs messages from tests
*/
test
}
protected static final char ABBREV_LEVEL_INFO = 'I';
protected static final char ABBREV_LEVEL_DEBUG = 'D';
protected static final char ABBREV_LEVEL_WARN = 'W';
protected static final char ABBREV_LEVEL_ERROR = 'E';
protected static final char ABBREV_LEVEL_TRACE = 'T';
public static final int LEVEL_EMERG = 0;
public static final int LEVEL_ALERT = 1;
public static final int LEVEL_CRIT = 2;
public static final int LEVEL_ERROR = 3;
public static final int LEVEL_WARN = 4;
public static final int LEVEL_NOTICE = 5;
public static final int LEVEL_INFO = 6;
public static final int LEVEL_DEBUG = 7;
public static final String FORMAT_PATTERN = "[ %c | %-20s | %-15s | %3d | %15s ] %s";
private static PrintStream out = System.out;
protected static Logging instance;
protected static boolean tracingEnabled = false;
private final int level;
private final int catMask;
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss");
/**
* Creates a new instance of Logging
*/
private Logging(int level, int catMask) {
if (level < 0)
this.level = 0;
else
this.level = level;
this.catMask = catMask;
instance = this;
System.currentTimeMillis();
}
public static void redirect(PrintStream out) {
Logging.out = out;
}
public static String truncateString(String string, int maxLength) {
return (string.length() > maxLength) ?
(string.substring(0, maxLength - 3) + "...") : string;
}
public static void logMessage(int level, Category cat, Object me, String formatPattern, Object... args) {
checkIfInitializedOrThrow();
// if the level is appropriate as well as the category, or the category
// is 'all', log the message
if (level <= instance.level && (cat == Category.all || (2 << cat.ordinal() & instance.catMask) > 0)) {
char levelName = getLevelName(level);
out.println(String.format(FORMAT_PATTERN, levelName,
me == null ? "-" : truncateString(me instanceof Class ? ((Class) me).getSimpleName(): me.getClass().getSimpleName(), 20),
truncateString(Thread.currentThread().getName(), 15),
Thread.currentThread().getId(),
getTimeStamp(),
String.format(formatPattern, args)));
}
}
private static void checkIfInitializedOrThrow() {
if (instance == null) {
throw new RuntimeException(
"Cannot log message because the logging is not initialized yet. Did you forget to call Logging.start(...) in your code?");
}
}
public static void logMessage(int level, Object me, String formatPattern, Object... args) {
logMessage(level, Category.all, me, formatPattern, args);
}
public static void logError(int level, Object me, Throwable msg) {
checkIfInitializedOrThrow();
// if the level is appropriate, log the message
if (level <= instance.level) {
char levelName = getLevelName(level);
out.println(String.format(FORMAT_PATTERN, levelName,
me == null ? "-" : (me instanceof Class ? ((Class) me).getSimpleName(): me.getClass().getSimpleName()),
Thread.currentThread().getName(), Thread.currentThread().getId(),
getTimeStamp(), msg.toString()));
for (StackTraceElement elem : msg.getStackTrace()) {
out.println(" ... " + elem.toString());
}
if (msg.getCause() != null) {
out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass()
.getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(),
getTimeStamp(), "root cause: " + msg.getCause()));
for (StackTraceElement elem : msg.getCause().getStackTrace()) {
out.println(" ... " + elem.toString());
}
}
}
}
public static void logUserError(int level, Category cat, Object me, Throwable msg) {
checkIfInitializedOrThrow();
// if the level is appropriate as well as the category, or the category
// is 'all', log the message
if (level <= instance.level && (cat == Category.all || (2 << cat.ordinal() & instance.catMask) > 0)) {
char levelName = getLevelName(level);
out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass()
.getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(),
getTimeStamp(), msg.toString()));
for (StackTraceElement elem : msg.getStackTrace()) {
out.println(" ... " + elem.toString());
}
}
}
public static char getLevelName(int level) {
switch (level) {
case LEVEL_EMERG:
case LEVEL_ALERT:
case LEVEL_CRIT:
case LEVEL_ERROR:
return ABBREV_LEVEL_ERROR;
case LEVEL_WARN:
return ABBREV_LEVEL_WARN;
case LEVEL_NOTICE:
case LEVEL_INFO:
return ABBREV_LEVEL_INFO;
case LEVEL_DEBUG:
return ABBREV_LEVEL_DEBUG;
default:
return '?';
}
}
public synchronized static void start(int level, Category... categories) {
if (instance == null) {
int catMask = 0;
for (Category cat : categories) {
if (cat == Category.all)
catMask = -1;
catMask |= 2 << cat.ordinal();
}
if(categories.length == 0)
catMask = -1;
instance = new Logging(level, catMask);
}
}
public static boolean isDebug() {
if (instance == null)
return false;
else
return instance.level >= LEVEL_DEBUG;
}
public static boolean isInfo() {
if (instance == null)
return false;
else
return instance.level >= LEVEL_INFO;
}
public static boolean isNotice() {
if (instance == null)
return false;
else
return instance.level >= LEVEL_NOTICE;
}
private static String getTimeStamp() {
return dateFormat.format(new Date());
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2008-2010 by Bjoern Kolbeck,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.logging;
/**
*
* @author bjko
*/
public class Utils {
public static final char LEVEL_INFO = 'I';
public static final char LEVEL_DEBUG = 'D';
public static final char LEVEL_WARN = 'W';
public static final char LEVEL_ERROR = 'E';
public static void logMessage(char level, Object me, String msg) {
if (me == null) {
System.out.println(String.format("[ %c | %-20s | %3d ] %s",
level,"?",Thread.currentThread().getId(),
msg));
} else {
System.out.println(String.format("[ %c | %-20s | %3d ] %s",
level,me.getClass().getSimpleName(),Thread.currentThread().getId(),
msg));
}
}
/** Creates a new instance of Utils */
public Utils() {
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2009-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.monitoring;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The class provides the ability to monitor data. It could monitor multiple data for each key.<br>
* NOTE: This class is thread-safe. <br>
* 22.07.2009
*/
public class ListMonitoring<V> extends Monitoring<List<V>> {
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (c) 2009-2010 by Christian Lorenz,
* Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.foundation.monitoring;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The class provides the ability to monitor data. The data must be added via push (put-method). For getting the
* contained data poll (get-method) and push (via listeners) is supported.<br>
* NOTE: This class is thread-safe. <br>
* 22.07.2009
*/
public class Monitoring<V> {
/**
* contains the monitored data
*/
protected ConcurrentHashMap<String, V> datasets;
/**
* contains the registered listeners
*/
protected ConcurrentHashMap<String, List<MonitoringListener<V>>> listeners;
/**
*
*/
public Monitoring() {
datasets = new ConcurrentHashMap<String, V>();
listeners = new ConcurrentHashMap<String, List<MonitoringListener<V>>>();
}
/**
* Adds the value to the given key and overwrites the old value. Notifies all associated listeners.
*
* @param key
* @param value
* @return
* @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
*/
public V put(String key, V value) {
assert (key != null && value != null);
V oldValue = datasets.put(key, value);
// check if listeners are registered
if (listeners.containsKey(key)) {
MonitoringEvent<V> event = new MonitoringEvent<V>(this, key, value);
for (MonitoringListener<V> listener : listeners.get(key))
listener.valueAddedOrChanged(event);
}
return oldValue;
}
/**
* @param key
* @return
* @see java.util.HashMap#get(java.lang.Object)
*/
public V get(String key) {
return datasets.get(key);
}
/**
* @param key
* @return
* @see java.util.HashMap#containsKey(java.lang.Object)
*/
public boolean containsKey(String key) {
return datasets.containsKey(key);
}
/**
* @return
* @see java.util.HashMap#entrySet()
*/
public Set<Entry<String, V>> entrySet() {
return datasets.entrySet();
}
/**
* @param key
* @return
* @see java.util.HashMap#remove(java.lang.Object)
*/
public V remove(String key) {
return datasets.remove(key);
}
/**
* @return
* @see java.util.HashMap#size()
*/
public int size() {
return datasets.size();
}
/**
* @return
* @see java.util.AbstractMap#toString()
*/
public String toString() {
return datasets.toString();
}
/**
* Registers a listener for the specified key. If the value of the key changes, the associated listeners
* will be notified.
*
* @param key
* @param listener
*/
public void registerListener(String key, MonitoringListener<V> listener) {
List<MonitoringListener<V>> list = listeners.get(key);
if (list == null) {
list = new CopyOnWriteArrayList<MonitoringListener<V>>();
listeners.put(key, list);
}
list.add(listener);
}
/**
* Unregisters the given listener for the given key.
*
* @param key
* @param listener
*/
public void unregisterListener(String key, MonitoringListener<V> listener) {
List<MonitoringListener<V>> list = listeners.get(key);
if (list != null) {
int index = list.indexOf(listener);
if (index != -1)
list.remove(index);
}
}
/*
* system-wide stuff
*/
private static boolean monitoringEnabled = false;
/**
* enables monitoring for the whole system
*/
public static void enable() {
monitoringEnabled = true;
}
/**
* @return the monitoringEnabled
*/
public static boolean isEnabled() {
return monitoringEnabled;
}
}

Some files were not shown because too many files have changed in this diff Show More