You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@giraph.apache.org by cl...@apache.org on 2014/01/20 19:53:39 UTC

[1/4] GIRAPH-803

Updated Branches:
  refs/heads/trunk 55e22de81 -> 5d1bc2de1


http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/src/site/resources/images/RexsterIO.svg
----------------------------------------------------------------------
diff --git a/src/site/resources/images/RexsterIO.svg b/src/site/resources/images/RexsterIO.svg
new file mode 100644
index 0000000..381492c
--- /dev/null
+++ b/src/site/resources/images/RexsterIO.svg
@@ -0,0 +1,1458 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="771.30359"
+   height="298.68527"
+   id="svg2"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="RexsterIO.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="956"
+     inkscape:window-height="1058"
+     id="namedview440"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="0.70789314"
+     inkscape:cx="447.18057"
+     inkscape:cy="148.91105"
+     inkscape:window-x="960"
+     inkscape:window-y="18"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" /><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><mask
+       id="mask142"><image
+         xlink:href="data:image/png;base64,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"
+         width="1"
+         height="1"
+         id="image144" /></mask><clipPath
+       id="clipPath184"><path
+         d="M 0,0 744,0 744,1052 0,1052 0,0 z"
+         id="path186"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath188"><path
+         d="M 744.234,305.906 C 744.281,190.66 572.457,97.223 360.488,97.223 148.52,97.223 -23.301,190.66 -23.258,305.906 -23.301,421.152 148.52,514.59 360.488,514.59 c 211.969,0 383.793,-93.438 383.746,-208.684 z"
+         id="path190"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath192"><path
+         d="m 7.75319,22.819608 33.236379,0 0,34.345386 -33.236379,0 0,-34.345386 z"
+         id="path194"
+         inkscape:connector-curvature="0" /></clipPath><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient196"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop198"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop200"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></radialGradient><mask
+       id="mask202"><g
+         id="g204"><g
+           clip-path="url(#clipPath192)"
+           id="g206"><path
+             d="m 7.75319,22.819608 33.236379,0 0,34.345386 -33.236379,0 0,-34.345386 z"
+             id="path208"
+             style="fill:url(#radialGradient196);stroke:none"
+             inkscape:connector-curvature="0" /></g></g></mask><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient210"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop212"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="0" /><stop
+         id="stop214"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="1" /></radialGradient><linearGradient
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875"
+       id="linearGradient216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"><stop
+         id="stop218"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="0" /><stop
+         id="stop220"
+         style="stop-color:#a5bfda;stop-opacity:1"
+         offset="0.31578901" /><stop
+         id="stop222"
+         style="stop-color:#376ca4;stop-opacity:1"
+         offset="1" /></linearGradient><linearGradient
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572"
+       id="linearGradient224"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"><stop
+         id="stop226"
+         style="stop-color:#204a87;stop-opacity:1"
+         offset="0" /><stop
+         id="stop228"
+         style="stop-color:#3465a4;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath230"><path
+         d="m 64,168 589,0 0,737 -589,0 0,-737 z"
+         id="path232"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient234"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"><stop
+         id="stop236"
+         style="stop-color:#ffffff;stop-opacity:0.54509807"
+         offset="0" /><stop
+         id="stop238"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></linearGradient><mask
+       id="mask240"><g
+         id="g242"><g
+           clip-path="url(#clipPath230)"
+           id="g244"><g
+             id="g246"><path
+               d="M 0,0 744,0 744,1052 0,1052 0,0 z"
+               id="path248"
+               style="fill:url(#linearGradient234);fill-opacity:1;fill-rule:nonzero;stroke:none"
+               inkscape:connector-curvature="0" /></g></g></g></mask><clipPath
+       id="clipPath250"><path
+         d="m 64,168 589,0 0,737 -589,0 0,-737 z"
+         id="path252"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient254"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"><stop
+         id="stop256"
+         style="stop-color:#3465a4;stop-opacity:1"
+         offset="0" /><stop
+         id="stop258"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="1" /></linearGradient><linearGradient
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962"
+       id="linearGradient260"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad"><stop
+         id="stop262"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop264"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath266"><path
+         d="m 138.488,681.688 7.551,-354.899 96.652,-27.184 -3.019,353.391 c 0,0 43.797,0 114.777,4.531 -110.277,4.926 -236.449,52.321 -279.39,83.059 29.957,-44.234 63.429,-58.898 63.429,-58.898 z"
+         id="path268"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath270"><path
+         d="m 10.7829,14.266165 13.243204,0 0,20.905343 -13.243204,0 0,-20.905343 z"
+         id="path272"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient274"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop276"
+         style="stop-color:#ffffff;stop-opacity:0.49411765"
+         offset="0" /><stop
+         id="stop278"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></linearGradient><mask
+       id="mask280"><g
+         id="g282"><g
+           clip-path="url(#clipPath270)"
+           id="g284"><path
+             d="m 10.7829,14.266165 13.243204,0 0,20.905343 -13.243204,0 0,-20.905343 z"
+             id="path286"
+             style="fill:url(#linearGradient274);stroke:none"
+             inkscape:connector-curvature="0" /></g></g></mask><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient288"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop290"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop292"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath362"><path
+         d="M 0,0 744,0 744,1052 0,1052 0,0 z"
+         id="path364"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath366"><path
+         d="M 744.234,305.906 C 744.281,190.66 572.457,97.223 360.488,97.223 148.52,97.223 -23.301,190.66 -23.258,305.906 -23.301,421.152 148.52,514.59 360.488,514.59 c 211.969,0 383.793,-93.438 383.746,-208.684 z"
+         id="path368"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath370"><path
+         d="m 7.75319,22.819608 33.236379,0 0,34.345386 -33.236379,0 0,-34.345386 z"
+         id="path372"
+         inkscape:connector-curvature="0" /></clipPath><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient374"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop376"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop378"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></radialGradient><mask
+       id="mask380"><g
+         id="g382"><g
+           clip-path="url(#clipPath370)"
+           id="g384"><path
+             d="m 7.75319,22.819608 33.236379,0 0,34.345386 -33.236379,0 0,-34.345386 z"
+             id="path386"
+             style="fill:url(#radialGradient374);stroke:none"
+             inkscape:connector-curvature="0" /></g></g></mask><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient388"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop390"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="0" /><stop
+         id="stop392"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="1" /></radialGradient><linearGradient
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875"
+       id="linearGradient394"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"><stop
+         id="stop396"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="0" /><stop
+         id="stop398"
+         style="stop-color:#a5bfda;stop-opacity:1"
+         offset="0.31578901" /><stop
+         id="stop400"
+         style="stop-color:#376ca4;stop-opacity:1"
+         offset="1" /></linearGradient><linearGradient
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572"
+       id="linearGradient402"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"><stop
+         id="stop404"
+         style="stop-color:#204a87;stop-opacity:1"
+         offset="0" /><stop
+         id="stop406"
+         style="stop-color:#3465a4;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath408"><path
+         d="m 64,168 589,0 0,737 -589,0 0,-737 z"
+         id="path410"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient412"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"><stop
+         id="stop414"
+         style="stop-color:#ffffff;stop-opacity:0.54509807"
+         offset="0" /><stop
+         id="stop416"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></linearGradient><mask
+       id="mask418"><g
+         id="g420"><g
+           clip-path="url(#clipPath408)"
+           id="g422"><g
+             id="g424"><path
+               d="M 0,0 744,0 744,1052 0,1052 0,0 z"
+               id="path426"
+               style="fill:url(#linearGradient412);fill-opacity:1;fill-rule:nonzero;stroke:none"
+               inkscape:connector-curvature="0" /></g></g></g></mask><clipPath
+       id="clipPath428"><path
+         d="m 64,168 589,0 0,737 -589,0 0,-737 z"
+         id="path430"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient432"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"><stop
+         id="stop434"
+         style="stop-color:#3465a4;stop-opacity:1"
+         offset="0" /><stop
+         id="stop436"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="1" /></linearGradient><linearGradient
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962"
+       id="linearGradient438"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad"><stop
+         id="stop440"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop442"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath444"><path
+         d="m 138.488,681.688 7.551,-354.899 96.652,-27.184 -3.019,353.391 c 0,0 43.797,0 114.777,4.531 -110.277,4.926 -236.449,52.321 -279.39,83.059 29.957,-44.234 63.429,-58.898 63.429,-58.898 z"
+         id="path446"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath448"><path
+         d="m 10.7829,14.266165 13.243204,0 0,20.905343 -13.243204,0 0,-20.905343 z"
+         id="path450"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient452"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop454"
+         style="stop-color:#ffffff;stop-opacity:0.49411765"
+         offset="0" /><stop
+         id="stop456"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></linearGradient><mask
+       id="mask458"><g
+         id="g460"><g
+           clip-path="url(#clipPath448)"
+           id="g462"><path
+             d="m 10.7829,14.266165 13.243204,0 0,20.905343 -13.243204,0 0,-20.905343 z"
+             id="path464"
+             style="fill:url(#linearGradient452);stroke:none"
+             inkscape:connector-curvature="0" /></g></g></mask><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient466"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop468"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop470"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath540"><path
+         d="M 0,0 744,0 744,1052 0,1052 0,0 z"
+         id="path542"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath544"><path
+         d="M 744.234,305.906 C 744.281,190.66 572.457,97.223 360.488,97.223 148.52,97.223 -23.301,190.66 -23.258,305.906 -23.301,421.152 148.52,514.59 360.488,514.59 c 211.969,0 383.793,-93.438 383.746,-208.684 z"
+         id="path546"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath548"><path
+         d="m 7.75319,22.819608 33.236379,0 0,34.345386 -33.236379,0 0,-34.345386 z"
+         id="path550"
+         inkscape:connector-curvature="0" /></clipPath><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient552"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop554"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop556"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></radialGradient><mask
+       id="mask558"><g
+         id="g560"><g
+           clip-path="url(#clipPath548)"
+           id="g562"><path
+             d="m 7.75319,22.819608 33.236379,0 0,34.345386 -33.236379,0 0,-34.345386 z"
+             id="path564"
+             style="fill:url(#radialGradient552);stroke:none"
+             inkscape:connector-curvature="0" /></g></g></mask><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient566"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop568"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="0" /><stop
+         id="stop570"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="1" /></radialGradient><linearGradient
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875"
+       id="linearGradient572"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"><stop
+         id="stop574"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="0" /><stop
+         id="stop576"
+         style="stop-color:#a5bfda;stop-opacity:1"
+         offset="0.31578901" /><stop
+         id="stop578"
+         style="stop-color:#376ca4;stop-opacity:1"
+         offset="1" /></linearGradient><linearGradient
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572"
+       id="linearGradient580"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"><stop
+         id="stop582"
+         style="stop-color:#204a87;stop-opacity:1"
+         offset="0" /><stop
+         id="stop584"
+         style="stop-color:#3465a4;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath586"><path
+         d="m 64,168 589,0 0,737 -589,0 0,-737 z"
+         id="path588"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient590"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"><stop
+         id="stop592"
+         style="stop-color:#ffffff;stop-opacity:0.54509807"
+         offset="0" /><stop
+         id="stop594"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></linearGradient><mask
+       id="mask596"><g
+         id="g598"><g
+           clip-path="url(#clipPath586)"
+           id="g600"><g
+             id="g602"><path
+               d="M 0,0 744,0 744,1052 0,1052 0,0 z"
+               id="path604"
+               style="fill:url(#linearGradient590);fill-opacity:1;fill-rule:nonzero;stroke:none"
+               inkscape:connector-curvature="0" /></g></g></g></mask><clipPath
+       id="clipPath606"><path
+         d="m 64,168 589,0 0,737 -589,0 0,-737 z"
+         id="path608"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient610"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"><stop
+         id="stop612"
+         style="stop-color:#3465a4;stop-opacity:1"
+         offset="0" /><stop
+         id="stop614"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="1" /></linearGradient><linearGradient
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962"
+       id="linearGradient616"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad"><stop
+         id="stop618"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop620"
+         style="stop-color:#729fcf;stop-opacity:1"
+         offset="1" /></linearGradient><clipPath
+       id="clipPath622"><path
+         d="m 138.488,681.688 7.551,-354.899 96.652,-27.184 -3.019,353.391 c 0,0 43.797,0 114.777,4.531 -110.277,4.926 -236.449,52.321 -279.39,83.059 29.957,-44.234 63.429,-58.898 63.429,-58.898 z"
+         id="path624"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath626"><path
+         d="m 10.7829,14.266165 13.243204,0 0,20.905343 -13.243204,0 0,-20.905343 z"
+         id="path628"
+         inkscape:connector-curvature="0" /></clipPath><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient630"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop632"
+         style="stop-color:#ffffff;stop-opacity:0.49411765"
+         offset="0" /><stop
+         id="stop634"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" /></linearGradient><mask
+       id="mask636"><g
+         id="g638"><g
+           clip-path="url(#clipPath626)"
+           id="g640"><path
+             d="m 10.7829,14.266165 13.243204,0 0,20.905343 -13.243204,0 0,-20.905343 z"
+             id="path642"
+             style="fill:url(#linearGradient630);stroke:none"
+             inkscape:connector-curvature="0" /></g></g></mask><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient644"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"><stop
+         id="stop646"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" /><stop
+         id="stop648"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1" /></linearGradient><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient4847"
+       xlink:href="#radialGradient210"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" /><linearGradient
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875"
+       id="linearGradient4849"
+       xlink:href="#linearGradient216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad" /><linearGradient
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572"
+       id="linearGradient4851"
+       xlink:href="#linearGradient224"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad" /><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient4853"
+       xlink:href="#linearGradient254"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad" /><linearGradient
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962"
+       id="linearGradient4855"
+       xlink:href="#linearGradient260"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad" /><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient4857"
+       xlink:href="#linearGradient288"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" /><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient4859"
+       xlink:href="#radialGradient388"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" /><linearGradient
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875"
+       id="linearGradient4861"
+       xlink:href="#linearGradient394"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad" /><linearGradient
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572"
+       id="linearGradient4863"
+       xlink:href="#linearGradient402"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad" /><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient4865"
+       xlink:href="#linearGradient432"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad" /><linearGradient
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962"
+       id="linearGradient4867"
+       xlink:href="#linearGradient438"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad" /><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient4869"
+       xlink:href="#linearGradient466"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" /><radialGradient
+       cx="23.857143"
+       cy="40"
+       r="17.142857"
+       fx="23.857143"
+       fy="40"
+       id="radialGradient4871"
+       xlink:href="#radialGradient566"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" /><linearGradient
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875"
+       id="linearGradient4873"
+       xlink:href="#linearGradient572"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad" /><linearGradient
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572"
+       id="linearGradient4875"
+       xlink:href="#linearGradient580"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad" /><linearGradient
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912"
+       id="linearGradient4877"
+       xlink:href="#linearGradient610"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad" /><linearGradient
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962"
+       id="linearGradient4879"
+       xlink:href="#linearGradient616"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad" /><linearGradient
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30"
+       id="linearGradient4881"
+       xlink:href="#linearGradient644"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#radialGradient210"
+       id="radialGradient3656"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"
+       cx="23.857143"
+       cy="40"
+       fx="23.857143"
+       fy="40"
+       r="17.142857" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient216"
+       id="linearGradient3658"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient224"
+       id="linearGradient3660"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient254"
+       id="linearGradient3662"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient260"
+       id="linearGradient3664"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad"
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient288"
+       id="linearGradient3666"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#radialGradient388"
+       id="radialGradient3668"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"
+       cx="23.857143"
+       cy="40"
+       fx="23.857143"
+       fy="40"
+       r="17.142857" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient394"
+       id="linearGradient3670"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient402"
+       id="linearGradient3672"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient432"
+       id="linearGradient3674"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient438"
+       id="linearGradient3676"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad"
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient466"
+       id="linearGradient3678"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#radialGradient566"
+       id="radialGradient3680"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"
+       cx="23.857143"
+       cy="40"
+       fx="23.857143"
+       fy="40"
+       r="17.142857" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient572"
+       id="linearGradient3682"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,-21.14292,-149.9615,1098.5062)"
+       spreadMethod="pad"
+       x1="9.3030529"
+       y1="26.71875"
+       x2="38.826412"
+       y2="26.71875" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient580"
+       id="linearGradient3684"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"
+       x1="25.064732"
+       y1="21.857143"
+       x2="25.207588"
+       y2="25.428572" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient610"
+       id="linearGradient3686"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.14292,0,0,21.14292,-149.9615,-256.61619)"
+       spreadMethod="pad"
+       x1="17.160095"
+       y1="14.004482"
+       x2="37.969398"
+       y2="56.575912" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient616"
+       id="linearGradient3688"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(21.93136,0,0,20.18343,-168.884,-221.97222)"
+       spreadMethod="pad"
+       x1="24"
+       y1="16.525082"
+       x2="24"
+       y2="13.284962" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient644"
+       id="linearGradient3690"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad"
+       x1="16.07143"
+       y1="19.5"
+       x2="15.785715"
+       y2="30" /></defs><g
+     transform="matrix(0.914575,0,0,-0.914575,614.24353,116.40216)"
+     id="g150"><g
+       transform="translate(-348.661,21.259)"
+       id="g152"><g
+         id="g154" /><g
+         transform="translate(348.661,-21.259)"
+         id="g156" /></g></g><g
+     transform="matrix(0.914575,0,0,-0.914575,614.24353,116.40216)"
+     id="g158"><g
+       transform="translate(-300.472,14.173)"
+       id="g160"><g
+         id="g162" /><g
+         transform="translate(300.472,-14.173)"
+         id="g164" /></g></g><g
+     transform="matrix(0.914575,0,0,-0.914575,614.24353,116.40216)"
+     id="g166"><g
+       transform="translate(-348.661,-113.386)"
+       id="g168"><g
+         id="g170" /><g
+         transform="translate(348.661,113.386)"
+         id="g172" /></g></g><g
+     transform="matrix(0.914575,0,0,-0.914575,119.66606,252.45891)"
+     id="g874" /><g
+     id="g3417"
+     transform="matrix(1.5,0,0,1.5,6.9021938e-4,0.00127598)"><g
+       id="g20"
+       transform="matrix(0.914575,0,0,-0.914575,485.69235,66.620222)"><g
+         id="g22"
+         transform="translate(-31.172,-28.347)"><g
+           id="g24"><g
+             id="g26"
+             transform="scale(62.3445,56.6929)"><image
+               id="image28"
+               transform="matrix(1,0,0,-1,0,1)"
+               height="1"
+               width="1"
+               xlink:href="data:image/png;base64,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

<TRUNCATED>

[2/4] GIRAPH-803

Posted by cl...@apache.org.
http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/rexster.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/rexster.xml b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/rexster.xml
new file mode 100644
index 0000000..9aebb89
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/rexster.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rexster>
+  <http>
+      <server-port>18182</server-port>
+      <server-host>127.0.0.1</server-host>
+      <base-uri>http://127.0.0.1</base-uri>
+      <web-root>public</web-root>
+      <character-set>UTF-8</character-set>
+      <enable-jmx>false</enable-jmx>
+      <enable-doghouse>false</enable-doghouse>
+      <thread-pool>
+          <worker>
+              <core-size>8</core-size>
+              <max-size>8</max-size>
+          </worker>
+          <kernal>
+              <core-size>4</core-size>
+              <max-size>4</max-size>
+          </kernal>
+      </thread-pool>
+      <io-strategy>leader-follower</io-strategy>
+  </http>
+  <script-engine-reset-threshold>-1</script-engine-reset-threshold>
+  <script-engine-init>data/init.groovy</script-engine-init>
+  <script-engines>gremlin-groovy</script-engines>
+  <graphs>
+    <!-- graph that will contain data for the Input Format test -->
+    <graph>
+      <graph-name>orientdb</graph-name>
+      <graph-type>orientgraph</graph-type>
+      <graph-location>local:/tmp/orientdb</graph-location>
+      <properties>
+        <username>admin</username>
+        <password>admin</password>
+        <mvrbtree.lazyUpdates>1</mvrbtree.lazyUpdates>
+      </properties>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+    <graph>
+      <graph-name>neodb</graph-name>
+      <graph-location>/tmp/neodb</graph-location>
+      <graph-type>neo4jgraph</graph-type>
+      <properties>
+        <neostore.nodestore.db.mapped_memory>285M</neostore.nodestore.db.mapped_memory>
+        <neostore.relationshipstore.db.mapped_memory>285M</neostore.relationshipstore.db.mapped_memory>
+        <neostore.propertystore.db.mapped_memory>100M</neostore.propertystore.db.mapped_memory>
+        <neostore.propertystore.db.strings.mapped_memory>100M</neostore.propertystore.db.strings.mapped_memory>
+        <neostore.propertystore.db.arrays.mapped_memory>10M</neostore.propertystore.db.arrays.mapped_memory>
+        <neostore.propertystore.db.index.mapped_memory>10M</neostore.propertystore.db.index.mapped_memory>
+        <neostore.propertystore.db.index.keys.mapped_memory>10M</neostore.propertystore.db.index.keys.mapped_memory>
+        <use_adaptive_cache>YES</use_adaptive_cache>
+        <adaptive_cache_heap_ratio>0.77</adaptive_cache_heap_ratio>
+        <adaptive_cache_manager_decrease_ratio>1.15</adaptive_cache_manager_decrease_ratio>
+        <adaptive_cache_manager_increase_ratio>1.1</adaptive_cache_manager_increase_ratio>
+        <adaptive_cache_worker_sleep_time>3000</adaptive_cache_worker_sleep_time>
+        <min_node_cache_size>0</min_node_cache_size>
+        <min_relationship_cache_size>0</min_relationship_cache_size>
+        <max_node_cache_size>1500</max_node_cache_size>
+        <max_relationship_cache_size>3500</max_relationship_cache_size>
+      </properties>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+    <graph>
+      <graph-name>tgdb</graph-name>
+      <graph-location>/tmp/tgdb</graph-location>
+      <graph-type>tinkergraph</graph-type>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+
+    <!-- graph that will be used for testing  -->
+    <graph>
+      <graph-name>emptyorientdb</graph-name>
+      <graph-type>orientgraph</graph-type>
+      <graph-location>local:/tmp/emptyorientdb</graph-location>
+      <properties>
+        <username>admin</username>
+        <password>admin</password>
+        <mvrbtree.lazyUpdates>"fuffa"</mvrbtree.lazyUpdates>
+      </properties>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+    <graph>
+      <graph-name>emptyneodb</graph-name>
+      <graph-location>/tmp/emptyneodb</graph-location>
+      <graph-type>neo4jgraph</graph-type>
+      <properties>
+        <neostore.nodestore.db.mapped_memory>285M</neostore.nodestore.db.mapped_memory>
+        <neostore.relationshipstore.db.mapped_memory>285M</neostore.relationshipstore.db.mapped_memory>
+        <neostore.propertystore.db.mapped_memory>100M</neostore.propertystore.db.mapped_memory>
+        <neostore.propertystore.db.strings.mapped_memory>100M</neostore.propertystore.db.strings.mapped_memory>
+        <neostore.propertystore.db.arrays.mapped_memory>10M</neostore.propertystore.db.arrays.mapped_memory>
+        <neostore.propertystore.db.index.mapped_memory>10M</neostore.propertystore.db.index.mapped_memory>
+        <neostore.propertystore.db.index.keys.mapped_memory>10M</neostore.propertystore.db.index.keys.mapped_memory>
+        <use_adaptive_cache>YES</use_adaptive_cache>
+        <adaptive_cache_heap_ratio>0.77</adaptive_cache_heap_ratio>
+        <adaptive_cache_manager_decrease_ratio>1.15</adaptive_cache_manager_decrease_ratio>
+        <adaptive_cache_manager_increase_ratio>1.1</adaptive_cache_manager_increase_ratio>
+        <adaptive_cache_worker_sleep_time>3000</adaptive_cache_worker_sleep_time>
+        <min_node_cache_size>0</min_node_cache_size>
+        <min_relationship_cache_size>0</min_relationship_cache_size>
+        <max_node_cache_size>1500</max_node_cache_size>
+        <max_relationship_cache_size>3500</max_relationship_cache_size>
+      </properties>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+    <graph>
+      <graph-name>emptytgdb</graph-name>
+      <graph-location>/tmp/emptytgdb</graph-location>
+      <graph-type>tinkergraph</graph-type>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+    <!-- empty database which is used to test for empty input -->
+    <graph>
+      <graph-name>emptydb</graph-name>
+      <graph-location>/tmp/emptydb</graph-location>
+      <graph-type>tinkergraph</graph-type>
+      <extensions>
+        <allows>
+          <allow>tp:gremlin</allow>
+          <allow>tp:giraph</allow>
+        </allows>
+      </extensions>
+    </graph>
+  </graphs>
+</rexster>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/tgdb-output.json
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/tgdb-output.json b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/tgdb-output.json
new file mode 100644
index 0000000..f4e61f3
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/tgdb-output.json
@@ -0,0 +1,5 @@
+[0,0,[[1,1]]]
+[1,0,[[2,5],[0,1],[3,1]]]
+[2,0,[[4,4],[1,2]]]
+[3,0,[[0,3],[4,4],[1,1]]]
+[4,0,[[3,4],[2,4]]]


[4/4] git commit: updated refs/heads/trunk to 5d1bc2d

Posted by cl...@apache.org.
GIRAPH-803


Project: http://git-wip-us.apache.org/repos/asf/giraph/repo
Commit: http://git-wip-us.apache.org/repos/asf/giraph/commit/5d1bc2de
Tree: http://git-wip-us.apache.org/repos/asf/giraph/tree/5d1bc2de
Diff: http://git-wip-us.apache.org/repos/asf/giraph/diff/5d1bc2de

Branch: refs/heads/trunk
Commit: 5d1bc2de1bc10eac795994772d17154b8c6b4e0a
Parents: 55e22de
Author: Claudio Martella <cl...@gmail.com>
Authored: Mon Jan 20 19:53:23 2014 +0100
Committer: Claudio Martella <cl...@gmail.com>
Committed: Mon Jan 20 19:53:23 2014 +0100

----------------------------------------------------------------------
 giraph-rexster/giraph-kibble/pom.xml            |   99 ++
 .../giraph-kibble/src/assembly/distribution.xml |   32 +
 .../giraph-kibble/src/assembly/standalone.xml   |   22 +
 .../giraph-kibble/src/main/assembly/compile.xml |   39 +
 .../giraph/rexster/kibble/GiraphExtension.java  |  381 +++++
 .../giraph/rexster/kibble/IteratorEdge.java     |   66 +
 .../giraph/rexster/kibble/IteratorVertex.java   |   65 +
 ...tinkerpop.rexster.extension.RexsterExtension |    1 +
 giraph-rexster/giraph-rexster-io/pom.xml        |  174 +++
 .../src/main/assembly/compile.xml               |   39 +
 .../rexster/conf/GiraphRexsterConstants.java    |  144 ++
 .../giraph/rexster/conf/package-info.java       |   21 +
 .../rexster/io/RexsterEdgeInputFormat.java      |  205 +++
 .../rexster/io/RexsterEdgeOutputFormat.java     |  257 +++
 .../giraph/rexster/io/RexsterInputSplit.java    |  112 ++
 .../rexster/io/RexsterVertexInputFormat.java    |  213 +++
 .../rexster/io/RexsterVertexOutputFormat.java   |  382 +++++
 ...RexsterLongDoubleDoubleEdgeOutputFormat.java |   68 +
 ...exsterLongDoubleDoubleVertexInputFormat.java |   81 +
 ...xsterLongDoubleDoubleVertexOutputFormat.java |   75 +
 .../RexsterLongDoubleEdgeInputFormat.java       |   91 ++
 .../RexsterLongDoubleFloatEdgeOutputFormat.java |   69 +
 ...RexsterLongDoubleFloatVertexInputFormat.java |   83 +
 ...exsterLongDoubleFloatVertexOutputFormat.java |   76 +
 .../RexsterLongFloatEdgeInputFormat.java        |   91 ++
 .../giraph/rexster/io/formats/package-info.java |   21 +
 .../apache/giraph/rexster/io/package-info.java  |   21 +
 .../giraph/rexster/utils/RexsterUtils.java      |  486 ++++++
 .../giraph/rexster/utils/package-info.java      |   21 +
 .../TestRexsterLongDoubleFloatIOFormat.java     |  519 +++++++
 .../rexster/io/formats/emptyneodb-output.json   |    5 +
 .../io/formats/emptyorientdb-output.json        |    5 +
 .../rexster/io/formats/emptytgdb-output.json    |    5 +
 .../giraph/rexster/io/formats/neodb-output.json |    5 +
 .../rexster/io/formats/orientdb-output.json     |    5 +
 .../giraph/rexster/io/formats/rexster.xml       |  155 ++
 .../giraph/rexster/io/formats/tgdb-output.json  |    5 +
 src/site/resources/images/RexsterIO.svg         | 1458 ++++++++++++++++++
 38 files changed, 5597 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/pom.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/pom.xml b/giraph-rexster/giraph-kibble/pom.xml
new file mode 100644
index 0000000..de13158
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/pom.xml
@@ -0,0 +1,99 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.giraph</groupId>
+    <artifactId>giraph-rexster</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>giraph-kibble</artifactId>
+  <url>http://giraph.apache.org/giraph-rexster/</url>
+  <name>Apache Giraph Rexster Kibble</name>
+  <description>Rexster Kibble for Rexster I/O</description>
+
+  <properties>
+    <top.dir>${project.basedir}/../..</top.dir>
+  </properties>
+
+  <build>
+    <directory>${project.basedir}/target</directory>
+    <finalName>${project.artifactId}-${project.version}</finalName>
+    <resources>
+      <resource>
+        <directory>${project.basedir}/src/main/resources
+        </directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>${project.basedir}/src/test/resources
+        </directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.tinkerpop.blueprints</groupId>
+      <artifactId>blueprints-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.tinkerpop.rexster</groupId>
+      <artifactId>rexster-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+      <version>1.17</version>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.17</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+      <version>1.3.3</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/assembly/distribution.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/assembly/distribution.xml b/giraph-rexster/giraph-kibble/src/assembly/distribution.xml
new file mode 100644
index 0000000..a097d6b
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/assembly/distribution.xml
@@ -0,0 +1,32 @@
+<assembly>
+  <id>distribution</id>
+  <formats>
+    <format>zip</format>
+  </formats>
+  <fileSets>
+    <fileSet>
+      <directory>src</directory>
+    </fileSet>
+    <fileSet>
+      <directory>target/apidocs</directory>
+    </fileSet>
+    <fileSet>
+      <directory>target/site</directory>
+    </fileSet>
+    <fileSet>
+      <directory>target</directory>
+      <includes>
+        <include>giraph-kibble-*.jar</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+  <files>
+    <file>
+      <source>pom.xml</source>
+      <outputDirectory>src</outputDirectory>
+    </file>
+    <file>
+      <outputDirectory>/</outputDirectory>
+    </file>
+  </files>
+</assembly>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/assembly/standalone.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/assembly/standalone.xml b/giraph-rexster/giraph-kibble/src/assembly/standalone.xml
new file mode 100644
index 0000000..4bc195b
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/assembly/standalone.xml
@@ -0,0 +1,22 @@
+<assembly>
+    <id>standalone</id>
+    <formats>
+        <format>jar</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+
+    <fileSets>
+        <fileSet>
+            <directory>target/classes</directory>
+            <outputDirectory>/</outputDirectory>
+        </fileSet>
+    </fileSets>
+
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <unpack>true</unpack>
+            <scope>runtime</scope>
+        </dependencySet>
+    </dependencySets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/main/assembly/compile.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/main/assembly/compile.xml b/giraph-rexster/giraph-kibble/src/main/assembly/compile.xml
new file mode 100644
index 0000000..b2e620f
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/main/assembly/compile.xml
@@ -0,0 +1,39 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+  <id>jar-with-dependencies</id>
+   <formats>
+    <format>jar</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+
+  <dependencySets>
+    <dependencySet>
+      <useProjectArtifact>true</useProjectArtifact>
+      <outputDirectory>/</outputDirectory>
+      <unpackOptions>
+        <excludes>
+          <exclude>META-INF/LICENSE</exclude>
+        </excludes>
+      </unpackOptions>
+      <unpack>true</unpack>
+      <scope>runtime</scope>
+    </dependencySet>
+  </dependencySets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/GiraphExtension.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/GiraphExtension.java b/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/GiraphExtension.java
new file mode 100644
index 0000000..a5348af
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/GiraphExtension.java
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.kibble;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONObject;
+
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Element;
+import com.tinkerpop.blueprints.Graph;
+import com.tinkerpop.blueprints.TransactionalGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.rexster.RexsterResourceContext;
+import com.tinkerpop.rexster.Tokens;
+import com.tinkerpop.rexster.extension.AbstractRexsterExtension;
+import com.tinkerpop.rexster.extension.ExtensionApi;
+import com.tinkerpop.rexster.extension.ExtensionDefinition;
+import com.tinkerpop.rexster.extension.ExtensionDescriptor;
+import com.tinkerpop.rexster.extension.ExtensionMethod;
+import com.tinkerpop.rexster.extension.ExtensionNaming;
+import com.tinkerpop.rexster.extension.ExtensionPoint;
+import com.tinkerpop.rexster.extension.ExtensionResponse;
+import com.tinkerpop.rexster.extension.HttpMethod;
+import com.tinkerpop.rexster.extension.RexsterContext;
+import com.tinkerpop.rexster.util.ElementHelper;
+import com.tinkerpop.rexster.util.RequestObjectHelper;
+
+/**
+ * This extension allows batch/transactional operations on a graph.
+ */
+@SuppressWarnings("rawtypes")
+@ExtensionNaming(namespace = GiraphExtension.EXTENSION_NAMESPACE,
+                 name = GiraphExtension.EXTENSION_NAME)
+public class GiraphExtension extends AbstractRexsterExtension {
+  public static final String EXTENSION_NAMESPACE = "tp";
+  public static final String EXTENSION_NAME = "giraph";
+  public static final String TX_KEY = "tx";
+  public static final String VLABEL_KEY = "vlabel";
+  public static final String DELAY_KEY = "delay";
+  public static final String RETRY_KEY = "retry";
+  /* element types */
+  private static final int VERTEX = 0;
+  private static final int EDGE = 1;
+  /* max time that will be waited for retry before giving up (msec.) */
+  private static final Logger logger = Logger.getLogger(GiraphExtension.class);
+  private int backoffRetry = 0;
+  private int backoffDelay = 0;
+  private String vlabel = null;
+  private String lastInVId = "";
+  private Vertex lastInV = null;
+
+  @ExtensionDefinition(extensionPoint = ExtensionPoint.GRAPH,
+                       method = HttpMethod.GET,
+                       path = "vertices")
+  @ExtensionDescriptor(description = "get vertices.",
+     api = {
+       @ExtensionApi(parameterName = Tokens.REXSTER + "." + Tokens.OFFSET_START,
+         description = "start offset."),
+       @ExtensionApi(parameterName = Tokens.REXSTER + "." + Tokens.OFFSET_END,
+         description = "end offset.")
+     })
+  public ExtensionResponse getVertices(
+    @RexsterContext final RexsterResourceContext context,
+    @RexsterContext final Graph graph) {
+
+    long start =
+      RequestObjectHelper.getStartOffset(context.getRequestObject());
+    long end =
+      RequestObjectHelper.getEndOffset(context.getRequestObject());
+
+    try {
+      Iterable<Vertex> vertices = graph.getVertices();
+      return ExtensionResponse.ok(new IteratorVertex(vertices.iterator(),
+        start, end));
+    } catch (Exception mqe) {
+      logger.error(mqe);
+      return ExtensionResponse.error("Error retrieving vertices.",
+                                     generateErrorJson());
+    }
+  }
+
+  @ExtensionDefinition(extensionPoint = ExtensionPoint.GRAPH,
+                       method = HttpMethod.GET,
+                       path = "edges")
+  @ExtensionDescriptor(description = "get edges.",
+     api = {
+       @ExtensionApi(parameterName = Tokens.REXSTER + "." + Tokens.OFFSET_START,
+         description = "start offset."),
+       @ExtensionApi(parameterName = Tokens.REXSTER + "." + Tokens.OFFSET_END,
+         description = "end offset.")
+     })
+  public ExtensionResponse getEdges(
+    @RexsterContext final RexsterResourceContext context,
+    @RexsterContext final Graph graph) {
+
+    long start =
+      RequestObjectHelper.getStartOffset(context.getRequestObject());
+    long end =
+      RequestObjectHelper.getEndOffset(context.getRequestObject());
+
+    try {
+      Iterable<Edge> edges = graph.getEdges();
+      return ExtensionResponse.ok(new IteratorEdge(edges.iterator(),
+        start, end));
+    } catch (Exception mqe) {
+      logger.error(mqe);
+      return ExtensionResponse.error("Error retrieving edges.",
+                                     generateErrorJson());
+    }
+  }
+
+  @ExtensionDefinition(
+    extensionPoint = ExtensionPoint.GRAPH,
+    method = HttpMethod.DELETE,
+    autoCommitTransaction = true)
+  @ExtensionDescriptor(description = "delete the graph content.")
+  public ExtensionResponse delete(
+      @RexsterContext RexsterResourceContext context,
+      @RexsterContext Graph graph) {
+
+    /* delete all the content of the graph (all edges and vertices) */
+    Iterable<Vertex> vertices = graph.getVertices();
+    Iterator<Vertex> it = vertices.iterator();
+    while(it.hasNext()) {
+      Vertex current = it.next();
+      graph.removeVertex(current);
+    }
+
+    Map<String, Object> resultMap = new HashMap<String, Object>();
+    resultMap.put(Tokens.SUCCESS, true);
+    return ExtensionResponse.ok(new JSONObject(resultMap));
+  }
+
+  @ExtensionDefinition(
+    extensionPoint = ExtensionPoint.GRAPH,
+    method = HttpMethod.POST,
+    path = "vertices",
+    autoCommitTransaction = false)
+  @ExtensionDescriptor(description = "add vertices to the graph.")
+  public ExtensionResponse postVertices(
+    @RexsterContext RexsterResourceContext context,
+    @RexsterContext Graph graph) {
+
+    ExtensionResponse response = handlePost(graph, context, VERTEX);
+
+    if (graph instanceof TransactionalGraph) {
+      TransactionalGraph tgraph = (TransactionalGraph) graph;
+      tgraph.commit();
+    }
+
+    return response;
+  }
+
+  @ExtensionDefinition(
+    extensionPoint = ExtensionPoint.GRAPH,
+    method = HttpMethod.POST,
+    path = "edges",
+    autoCommitTransaction = false)
+  @ExtensionDescriptor(description = "add edges to the graph.")
+  public ExtensionResponse postEdges(
+    @RexsterContext RexsterResourceContext context,
+    @RexsterContext Graph graph) {
+
+    return handlePost(graph, context, EDGE);
+  }
+
+  public ExtensionResponse handlePost(Graph graph,
+    RexsterResourceContext context, int type) {
+
+    JSONObject tx = context.getRequestObject();
+    if (tx == null) {
+      ExtensionMethod extMethod = context.getExtensionMethod();
+      return ExtensionResponse.error("no transaction JSON posted", null,
+               Response.Status.BAD_REQUEST.getStatusCode(), null,
+               generateErrorJson(extMethod.getExtensionApiAsJson()));
+    }
+
+    try {
+      vlabel = tx.getString(VLABEL_KEY);
+      if (tx.has(DELAY_KEY)) {
+        backoffDelay = tx.getInt(DELAY_KEY);
+      }
+      if (tx.has(RETRY_KEY)) {
+        backoffRetry = tx.getInt(RETRY_KEY);
+      }
+      JSONArray array = tx.optJSONArray(TX_KEY);
+
+      for (int i = 0; i < array.length(); i++) {
+        JSONObject element = array.optJSONObject(i);
+        createElement(element, graph, type);
+      }
+
+      Map<String, Object> resultMap = new HashMap<String, Object>();
+      resultMap.put(Tokens.SUCCESS, true);
+      resultMap.put("txProcessed", array.length());
+
+      return ExtensionResponse.ok(new JSONObject(resultMap));
+
+    } catch (IllegalArgumentException iae) {
+      logger.error(iae);
+      ExtensionMethod extMethod = context.getExtensionMethod();
+      return ExtensionResponse.error(iae.getMessage(), null,
+               Response.Status.BAD_REQUEST.getStatusCode(), null,
+               generateErrorJson(extMethod.getExtensionApiAsJson()));
+    } catch (Exception ex) {
+      logger.error(ex);
+      return ExtensionResponse.error("Error executing transaction: " +
+               ex.getMessage(), generateErrorJson());
+    }
+  }
+
+  private void createElement(JSONObject element, Graph graph, int type)
+    throws Exception {
+
+    switch (type) {
+      case VERTEX:
+        String id = element.optString(vlabel);
+        Vertex vertex = getVertex(graph, id);
+        if (vertex != null) {
+          throw new Exception("Vertex with id " + id + " already exists.");
+        }
+        vertex = graph.addVertex(null);
+        vertex.setProperty(vlabel, id);
+
+        accumulateAttributes(vertex, element);
+        break;
+      case EDGE:
+        String inV = getProperty(element, Tokens._IN_V, null);
+        String outV = getProperty(element, Tokens._OUT_V, null);
+        String label = getProperty(element, Tokens._LABEL, "none");
+
+        if (outV == null || inV == null || outV.isEmpty() || inV.isEmpty()) {
+          throw new IllegalArgumentException("an edge must specify a "
+                      + Tokens._IN_V + " and " + Tokens._OUT_V);
+        }
+
+        // there is no edge but the in/out vertex params and label are present
+        // so validate that the vertexes are present before creating the edge
+        addEdge(graph, element, outV, inV, label);
+        break;
+      default:
+        throw new Exception("Element type unknown.");
+    }
+  }
+
+  private void addEdge(Graph graph, JSONObject element, String outV,
+    String inV, String label) throws Exception {
+
+    Edge edge;
+    Exception prevException = new
+      RuntimeException("Exception initialized when trying commit.");
+    int retryCount = 0;
+
+    while (retryCount <= backoffRetry) {
+      // The first time the attempt is made to save the edge, no back off is
+      // needed and so the thread is not put to sleep. Differently, afterwards
+      // if needed the delay is exponentially (but randomly) put to sleep.
+      if (retryCount > 0) {
+        try {
+          double delay = backoffDelay * Math.pow(2, retryCount);
+          Thread.sleep((long) delay);
+        } catch (InterruptedException ie) {
+          /* nothing to do */
+        }
+      }
+      retryCount += 1;
+
+      Vertex in = getInputVertex(graph, inV);
+      Vertex out = getVertex(graph, outV);
+      if (out == null || in == null) {
+        throw new Exception("the " + Tokens._IN_V + " or " +
+                           Tokens._OUT_V + " vertices could not be found.");
+      }
+
+      edge = graph.addEdge(null, out, in, label);
+      accumulateAttributes(edge, element);
+      if (graph instanceof TransactionalGraph) {
+        TransactionalGraph tgraph = (TransactionalGraph) graph;
+        try {
+          tgraph.commit();
+          return;
+        } catch (Exception e) {
+          tgraph.rollback();
+          logger.warn("Exception thrown while saving edge: " + e.toString());
+          logger.warn("retry: " + retryCount);
+          /* need to work out the Exceptions to handle?! */
+          prevException = e;
+        }
+      } else {
+        return;
+      }
+    }
+
+    throw new RuntimeException(prevException);
+  }
+
+  private void accumulateAttributes(Element element, JSONObject obj)
+    throws Exception {
+
+    Iterator keys = obj.keys();
+    while (keys.hasNext()) {
+      String key = keys.next().toString();
+      if (!key.startsWith(Tokens.UNDERSCORE)) {
+        element.setProperty(key,
+          ElementHelper.getTypedPropertyValue(obj.getString(key)));
+      }
+    }
+  }
+
+  /**
+   * Utility function to get a property from the JSON object with the specified
+   * label as a String value.
+   *
+   * @param element JSON object
+   * @param label label of the element to retrieve
+   * @param defaultValue set to a value != null if a default value is needed
+   * @return value of the associated label or null
+   */
+  private String getProperty(JSONObject element, String label,
+    String defaultValue) {
+
+    String value = null;
+    Object tmp = element.opt(label);
+    if (tmp != null) {
+      value = tmp.toString();
+    }
+    if (value == null) {
+      value = defaultValue;
+    }
+    return value;
+  }
+
+  private Vertex getInputVertex(Graph graph, String inV) {
+    Vertex in = null;
+    if (inV.equals(lastInVId)) {
+      in = lastInV;
+    } else {
+      lastInVId = inV;
+      in = getVertex(graph, inV);
+      lastInV = in;
+    }
+    return in;
+  }
+
+  private Vertex getVertex(Graph graph, String v) {
+    Vertex vertex;
+    Iterable<Vertex> vertexes = graph.getVertices(vlabel, v);
+    Iterator<Vertex> itvertex = vertexes.iterator();
+    if (!itvertex.hasNext()) {
+      return null;
+    }
+    vertex = itvertex.next();
+    if (itvertex.hasNext()) {
+      return null;
+    }
+    return vertex;
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorEdge.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorEdge.java b/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorEdge.java
new file mode 100644
index 0000000..e8a325d
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorEdge.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.kibble;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Element;
+
+class IteratorEdge implements Iterator<Element> {
+  private Iterator<Edge> edges = null;
+  private long start;
+  private long end;
+  private long counter;
+
+  public IteratorEdge(Iterator<Edge> edges, long start, long end) {
+    this.edges = edges;
+    this.start = start;
+    this.end = end;
+    this.counter = 0;
+  }
+
+  @Override
+  public boolean hasNext() {
+    if (counter >= this.end) {
+      return false;
+    }
+    return edges.hasNext();
+  }
+
+  @Override
+  public Element next() {
+    while (counter < this.start) {
+      edges.next();
+      counter += 1;
+    }
+
+    if (counter >= this.start && counter < this.end) {
+      counter += 1;
+      return edges.next();
+    }
+
+    throw new NoSuchElementException();
+  }
+
+  @Override
+  public void remove() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorVertex.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorVertex.java b/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorVertex.java
new file mode 100644
index 0000000..3332f48
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/main/java/org/apache/giraph/rexster/kibble/IteratorVertex.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.kibble;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.tinkerpop.blueprints.Element;
+import com.tinkerpop.blueprints.Vertex;
+
+class IteratorVertex implements Iterator<Element> {
+  private Iterator<Vertex> vertices = null;
+  private long start;
+  private long end;
+  private long counter;
+
+  public IteratorVertex(Iterator<Vertex> vertices, long start, long end) {
+    this.vertices = vertices;
+    this.start = start;
+    this.end = end;
+    this.counter = 0;
+  }
+
+  @Override
+  public boolean hasNext() {
+    if (counter >= this.end) {
+      return false;
+    }
+    return vertices.hasNext();
+  }
+
+  @Override
+  public Element next() {
+    while (counter < this.start) {
+      vertices.next();
+      counter++;
+    }
+
+    if (counter >= this.start && counter < this.end) {
+      return vertices.next();
+    }
+
+    throw new NoSuchElementException();
+  }
+
+  @Override
+  public void remove() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-kibble/src/main/resources/META-INF/services/com.tinkerpop.rexster.extension.RexsterExtension
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-kibble/src/main/resources/META-INF/services/com.tinkerpop.rexster.extension.RexsterExtension b/giraph-rexster/giraph-kibble/src/main/resources/META-INF/services/com.tinkerpop.rexster.extension.RexsterExtension
new file mode 100644
index 0000000..76ef348
--- /dev/null
+++ b/giraph-rexster/giraph-kibble/src/main/resources/META-INF/services/com.tinkerpop.rexster.extension.RexsterExtension
@@ -0,0 +1 @@
+org.apache.giraph.rexster.kibble.GiraphExtension

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/pom.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/pom.xml b/giraph-rexster/giraph-rexster-io/pom.xml
new file mode 100644
index 0000000..3553552
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/pom.xml
@@ -0,0 +1,174 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.giraph</groupId>
+    <artifactId>giraph-rexster</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>giraph-rexster-io</artifactId>
+  <packaging>jar</packaging>
+
+  <name>Apache Giraph Rexster I/O Formats</name>
+  <url>http://giraph.apache.org/giraph-rexster/</url>
+  <description>Giraph Rexster input/output classes</description>
+
+  <properties>
+    <top.dir>${project.basedir}/../..</top.dir>
+  </properties>
+
+  <build>
+    <testResources>
+      <testResource>
+        <directory>${project.basedir}/src/test/resources</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-site-plugin</artifactId>
+        <configuration>
+          <siteDirectory>${project.basedir}/src/site</siteDirectory>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.6</version>
+        <configuration>
+          <systemProperties>
+            <property>
+              <name>prop.jarLocation</name>
+              <value>${top.dir}/giraph-core/target/giraph-${project.version}-${forHadoop}-jar-with-dependencies.jar</value>
+            </property>
+          </systemProperties>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <!-- compile dependencies. sorted lexicographically. -->
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-configuration</groupId>
+      <artifactId>commons-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.giraph</groupId>
+      <artifactId>giraph-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.zookeeper</groupId>
+      <artifactId>zookeeper</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+      <version>1.3.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+    </dependency>
+
+    <!-- test dependencies. sorted lexicographically. -->
+    <dependency>
+      <groupId>com.tinkerpop.blueprints</groupId>
+      <artifactId>blueprints-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.tinkerpop.rexster</groupId>
+      <artifactId>rexster-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.tinkerpop.rexster</groupId>
+      <artifactId>rexster-protocol</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.tinkerpop.rexster</groupId>
+      <artifactId>rexster-server</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.tinkerpop.blueprints</groupId>
+      <artifactId>blueprints-orient-graph</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.tinkerpop.blueprints</groupId>
+      <artifactId>blueprints-neo4j-graph</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.giraph</groupId>
+      <artifactId>giraph-kibble</artifactId>
+      <version>${project.version}</version>
+      <scope>system</scope>
+      <systemPath>${top.dir}/giraph-rexster/giraph-kibble/target/giraph-kibble-${project.version}.jar</systemPath>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/assembly/compile.xml
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/assembly/compile.xml b/giraph-rexster/giraph-rexster-io/src/main/assembly/compile.xml
new file mode 100644
index 0000000..fcaffa6
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/assembly/compile.xml
@@ -0,0 +1,39 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+  <id>jar-with-dependencies</id>
+   <formats>
+    <format>jar</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+
+  <dependencySets>
+    <dependencySet>
+      <useProjectArtifact>true</useProjectArtifact>
+      <outputDirectory>/</outputDirectory>
+      <unpackOptions>
+          <excludes>
+              <exclude>META-INF/LICENSE</exclude>
+          </excludes>
+      </unpackOptions>
+      <unpack>true</unpack>
+      <scope>runtime</scope>
+    </dependencySet>
+  </dependencySets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/GiraphRexsterConstants.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/GiraphRexsterConstants.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/GiraphRexsterConstants.java
new file mode 100644
index 0000000..b4c6a83
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/GiraphRexsterConstants.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.conf;
+
+import org.apache.giraph.conf.StrConfOption;
+import org.apache.giraph.conf.IntConfOption;
+import org.apache.giraph.conf.BooleanConfOption;
+
+/**
+ * Constants used all over Giraph for configuration specific for Rexster
+ * REST API.
+ */
+// CHECKSTYLE: stop InterfaceIsTypeCheck
+public interface GiraphRexsterConstants {
+  // ------------ GENERAL CONFIGURATIONS
+  /** Rexster hostname which provides the REST API. */
+  StrConfOption GIRAPH_REXSTER_HOSTNAME =
+    new StrConfOption("giraph.rexster.hostname", null,
+                      "Rexster hostname which provides the REST API. " +
+                      "- required");
+  /** Rexster port where to contact the REST API. */
+  IntConfOption GIRAPH_REXSTER_PORT =
+    new IntConfOption("giraph.rexster.port", 8182,
+                      "Rexster port where to contact the REST API.");
+  /** Rexster flag to set the connection over SSL instaed of clear-text. */
+  BooleanConfOption GIRAPH_REXSTER_USES_SSL =
+    new BooleanConfOption("giraph.rexster.ssl", false,
+                          "Rexster flag to set the connection over SSL " +
+                          "instaed of clear-text.");
+  /** Rexster username to access the REST API. */
+  StrConfOption GIRAPH_REXSTER_USERNAME =
+    new StrConfOption("giraph.rexster.username", "",
+                      "Rexster username to access the REST API.");
+  /** Rexster password to access the REST API. */
+  StrConfOption GIRAPH_REXSTER_PASSWORD =
+    new StrConfOption("giraph.rexster.password", "",
+                      "Rexster password to access the REST API.");
+
+  // ------------ INPUT FORMAT CONFIGURATIONS
+  /** Rexster input graph. */
+  StrConfOption GIRAPH_REXSTER_INPUT_GRAPH =
+    new StrConfOption("giraph.rexster.input.graph", "graphdb",
+                      "Rexster input graph.");
+  /** Rexster number of estimated vertexes in the graph to be loaded.  */
+  IntConfOption GIRAPH_REXSTER_V_ESTIMATE =
+    new IntConfOption("giraph.rexster.input.vertex", 1000,
+                      "Rexster number of estimated vertexes in the " +
+                      "graph to be loaded.");
+  /** Rexster number of estimated edges in the graph to be loaded.  */
+  IntConfOption GIRAPH_REXSTER_E_ESTIMATE =
+    new IntConfOption("giraph.rexster.input.edges", 1000,
+                      "Rexster number of estimated vertex in the " +
+                      "graph to be loaded.");
+  /** If the database is Gremlin enabled, the script will be used to retrieve
+      the vertexes from the Rexster exposed database. */
+  StrConfOption GIRAPH_REXSTER_GREMLIN_V_SCRIPT =
+    new StrConfOption("giraph.rexster.input.vertex.gremlinScript", "",
+                      "If the database is Gremlin enabled, the script will " +
+                      "be used to retrieve the vertexes from the Rexster " +
+                      "exposed database.");
+  /** If the database is Gremlin enabled, the script will be used to retrieve
+      the edges from the Rexster exposed database. */
+  StrConfOption GIRAPH_REXSTER_GREMLIN_E_SCRIPT =
+    new StrConfOption("giraph.rexster.input.edges.gremlinScript", "",
+                      "If the database is Gremlin enabled, the script will " +
+                      "be used to retrieve the edges from the Rexster " +
+                      "exposed database.");
+
+  // ------------ OUTPUT FORMAT CONFIGURATIONS
+  /** Rexster output graph. */
+  StrConfOption GIRAPH_REXSTER_OUTPUT_GRAPH =
+    new StrConfOption("giraph.rexster.output.graph", "graphdb",
+                      "Rexster output graph.");
+  /** Rexster Vertex ID label for the JSON format. */
+  StrConfOption GIRAPH_REXSTER_VLABEL =
+    new StrConfOption("giraph.rexster.output.vlabel", "_vid",
+                      "Rexster Vertex ID label for the JSON format.");
+  /**
+   * Rexster back-off delay in milliseconds which is multiplied to an
+   * exponentially increasing counter. Needed to deal with deadlocks and
+   * consistency raised by the graph database.
+   **/
+  IntConfOption GIRAPH_REXSTER_BACKOFF_DELAY =
+    new IntConfOption("giraph.rexster.output.backoffDelay", 5,
+                      "Rexster back-off delay in milliseconds which is " +
+                      "multiplied to an exponentially increasing counter. " +
+                      "Needed to deal with deadlocks and consistency raised " +
+                      "by the graph database.");
+  /**
+   * Rexster back-off number of retries in case of failures.
+   * Needed to deal with deadlocks and consistency raised by the
+   * graphdatabase.
+   **/
+  IntConfOption GIRAPH_REXSTER_BACKOFF_RETRY =
+    new IntConfOption("giraph.rexster.output.backoffRetry", 20,
+                      "Rexster back-off number of retries in case of " +
+                      "failures. Needed to deal with deadlocks and " +
+                      "consistency raised by the graph database.");
+  /**
+   * Rexster output format wait timeout (seconds). This is used to wake up
+   * the thread to call progress very x seconds if not progress from the
+   * ZooKeeper is detected.
+   */
+  IntConfOption GIRAPH_REXSTER_OUTPUT_WAIT_TIMEOUT =
+    new IntConfOption("giraph.rexster.output.timeout", 10,
+                      "Rexster output format wait timeout (seconds). This is " +
+                      "used to wake up the thread to call progress very x " +
+                      "seconds if not progress from the ZooKeeper is " +
+                      "detected.");
+  /**
+   * Rexster Output format transaction size. This parameter defines how many
+   * vertices are sent for each transaction.
+   */
+  IntConfOption GIRAPH_REXSTER_OUTPUT_V_TXSIZE =
+    new IntConfOption("giraph.rexster.output.vertex.txsize", 1000,
+                      "Rexster Output format transaction size. This parameter" +
+                      "defines how many vertexes are sent for each " +
+                      "transaction.");
+  /**
+   * Rexster Output format transaction size. This parameter defines how many
+   * edges are sent for each transaction.
+   */
+  IntConfOption GIRAPH_REXSTER_OUTPUT_E_TXSIZE =
+    new IntConfOption("giraph.rexster.output.edge.txsize", 1000,
+                      "Rexster Output format transaction size. This parameter" +
+                      "defines how many edges are sent for each " +
+                      "transaction.");
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/package-info.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/package-info.java
new file mode 100644
index 0000000..b4917bc
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/conf/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Package of configuration information for Rexster in Giraph.
+ */
+package org.apache.giraph.rexster.conf;

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeInputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeInputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeInputFormat.java
new file mode 100644
index 0000000..b21a4e2
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeInputFormat.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io;
+
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_E_ESTIMATE;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_HOSTNAME;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.io.EdgeInputFormat;
+import org.apache.giraph.io.EdgeReader;
+import org.apache.giraph.rexster.utils.RexsterUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.io.WritableComparable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+/**
+ * Abstract class that users should subclass to use their own Rexster based
+ * vertex input format. This class was inspired by the Rexster Input format
+ * available in Faunus authored by Stephen Mallette.
+ * @param <I>   Vertex id
+ * @param <E>   Edge data
+ */
+@SuppressWarnings("rawtypes")
+public abstract class RexsterEdgeInputFormat<I extends WritableComparable,
+  E extends Writable> extends EdgeInputFormat<I, E> {
+
+  /** Class logger. */
+  private static final Logger LOG =
+      Logger.getLogger(RexsterEdgeInputFormat.class);
+
+  /**
+   * @param conf configuration parameters
+   */
+  public void checkInputSpecs(Configuration conf) {
+    GiraphConfiguration gconf = new GiraphConfiguration(conf);
+    String msg = "Rexster InputFormat usage requires both Edge and Vertex " +
+                 "InputFormat's.";
+
+    /* check for Vertex InputFormat since both are required by Rexster */
+    if (!gconf.hasVertexInputFormat()) {
+      LOG.error(msg);
+      throw new RuntimeException(msg);
+    }
+
+    String endpoint = GIRAPH_REXSTER_HOSTNAME.get(conf);
+    if (endpoint == null) {
+      throw new RuntimeException(GIRAPH_REXSTER_HOSTNAME.getKey() +
+                                 " is a mandatory parameter.");
+    }
+  }
+
+  @Override
+  public List<InputSplit> getSplits(JobContext context, int minSplitCountHint)
+    throws IOException, InterruptedException {
+
+    return RexsterUtils.getSplits(context,
+      GIRAPH_REXSTER_E_ESTIMATE.get(getConf()));
+  }
+
+  @Override
+  public abstract RexsterEdgeReader createEdgeReader(InputSplit split,
+      TaskAttemptContext context) throws IOException;
+
+  /**
+   * Abstract class to be implemented by the user based on their specific
+   * vertex input. Easiest to ignore the key value separator and only use
+   * key instead.
+   */
+  protected abstract class RexsterEdgeReader extends EdgeReader<I, E> {
+
+    /** Input stream from the HTTP connection to the REST endpoint */
+    private BufferedReader rexsterBufferedStream;
+    /** JSON parser/tokenizer object */
+    private JSONTokener tokener;
+    /** start index of the Rexster paging */
+    private long splitStart;
+    /** end index of the Rexster paging */
+    private long splitEnd;
+    /** number of iterated items */
+    private long itemsIterated = 0;
+    /** current edge obtained from Rexster */
+    private Edge<I, E> edge;
+    /** first call to the nextEdge fuction */
+    private boolean isFirstEdge;
+
+    @Override
+    public void initialize(InputSplit inputSplit, TaskAttemptContext context)
+      throws IOException, InterruptedException {
+
+      RexsterInputSplit rexsterInputSplit = (RexsterInputSplit) inputSplit;
+      splitEnd = rexsterInputSplit.getEnd();
+      splitStart = rexsterInputSplit.getStart();
+
+      rexsterBufferedStream =
+        RexsterUtils.Edge.openInputStream(getConf(), splitStart, splitEnd);
+      tokener = RexsterUtils.parseJSONEnvelope(rexsterBufferedStream);
+      isFirstEdge = true;
+    }
+
+    @Override
+    public void close() throws IOException {
+      rexsterBufferedStream.close();
+    }
+
+    @Override
+    public float getProgress() throws IOException, InterruptedException {
+      final float estimated = GIRAPH_REXSTER_E_ESTIMATE.get(getConf());
+
+      if (this.splitStart == this.splitEnd) {
+        return 0.0f;
+      } else {
+        /* assuming you got the estimate right this progress should be
+           pretty close; */
+        return Math.min(1.0f, this.itemsIterated / (float) estimated);
+      }
+    }
+
+    @Override
+    public Edge<I, E> getCurrentEdge()
+      throws IOException, InterruptedException {
+
+      return edge;
+    }
+
+    @Override
+    public boolean nextEdge() throws IOException, InterruptedException {
+      try {
+        /* if the tokener was not set, no objects are in fact available */
+        if (this.tokener == null) {
+          return false;
+        }
+
+        char c;
+        if (isFirstEdge) {
+          c = this.tokener.nextClean();
+
+          isFirstEdge = false;
+          if (c == RexsterUtils.END_ARRAY) {
+            return false;
+          }
+          tokener.back();
+        }
+
+        JSONObject obj = new JSONObject(this.tokener);
+        edge = parseEdge(obj);
+        LOG.info(edge);
+
+        c = tokener.nextClean();
+        if (c == RexsterUtils.ARRAY_SEPARATOR) {
+          itemsIterated += 1;
+          return true;
+        } else if (c == RexsterUtils.END_ARRAY) {
+          return false;
+        } else {
+          LOG.error(String.format("Expected a '%c' at the end of the array",
+                                  RexsterUtils.END_ARRAY));
+          throw new InterruptedException();
+        }
+      } catch (JSONException e) {
+        throw new InterruptedException(e.toString());
+      }
+    }
+
+    /**
+     * Parser for a single edge JSON object
+     *
+     * @param   jsonEdge edge represented as JSON object
+     * @return  The edge object associated with the JSON object
+     */
+    protected abstract Edge<I, E> parseEdge(JSONObject jsonEdge)
+      throws JSONException;
+
+    @Override
+    public abstract I getCurrentSourceId()
+      throws IOException, InterruptedException;
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeOutputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeOutputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeOutputFormat.java
new file mode 100644
index 0000000..ca4e861
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterEdgeOutputFormat.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io;
+
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_OUTPUT_E_TXSIZE;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_VLABEL;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_HOSTNAME;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_BACKOFF_DELAY;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_BACKOFF_RETRY;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.nio.charset.Charset;
+
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.io.EdgeOutputFormat;
+import org.apache.giraph.io.EdgeWriter;
+import org.apache.giraph.rexster.utils.RexsterUtils;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.io.WritableComparable;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.hadoop.mapreduce.OutputCommitter;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Abstract class that users should subclass to use their own Rexster based
+ * edge output format.
+ *
+ * @param <I>
+ * @param <V>
+ * @param <E>
+ */
+@SuppressWarnings("rawtypes")
+public class RexsterEdgeOutputFormat<I extends WritableComparable,
+  V extends Writable, E extends Writable>
+  extends EdgeOutputFormat<I, V, E> {
+
+  /** Class logger. */
+  private static final Logger LOG =
+      Logger.getLogger(RexsterEdgeOutputFormat.class);
+
+  @Override
+  public RexsterEdgeWriter
+  createEdgeWriter(TaskAttemptContext context)
+    throws IOException, InterruptedException {
+
+    return new RexsterEdgeWriter();
+  }
+
+  @Override
+  public void checkOutputSpecs(JobContext context)
+    throws IOException, InterruptedException {
+    GiraphConfiguration gconf =
+      new GiraphConfiguration(context.getConfiguration());
+    String msg = "Rexster OutputFormat usage requires both Edge and " +
+                 "Vertex OutputFormat's.";
+
+    if (!gconf.hasVertexOutputFormat()) {
+      LOG.error(msg);
+      throw new InterruptedException(msg);
+    }
+
+    String endpoint = GIRAPH_REXSTER_HOSTNAME.get(gconf);
+    if (endpoint == null) {
+      throw new InterruptedException(GIRAPH_REXSTER_HOSTNAME.getKey() +
+                                     " is a mandatory parameter.");
+    }
+  }
+
+  @Override
+  public OutputCommitter getOutputCommitter(TaskAttemptContext context)
+    throws IOException, InterruptedException {
+
+    return new NullOutputCommitter();
+  }
+
+  /**
+   * Empty output commiter for hadoop.
+   */
+  private static class NullOutputCommitter extends OutputCommitter {
+    @Override
+    public void abortTask(TaskAttemptContext taskContext) { }
+
+    @Override
+    public void cleanupJob(JobContext jobContext) { }
+
+    @Override
+    public void commitTask(TaskAttemptContext taskContext) { }
+
+    @Override
+    public boolean needsTaskCommit(TaskAttemptContext taskContext) {
+      return false;
+    }
+
+    @Override
+    public void setupJob(JobContext jobContext) { }
+
+    @Override
+    public void setupTask(TaskAttemptContext taskContext) { }
+  }
+
+  /**
+   * Abstract class to be implemented by the user based on their specific
+   * vertex/edges output. Easiest to ignore the key value separator and only
+   * use key instead.
+   */
+  protected class RexsterEdgeWriter extends EdgeWriter<I, V, E> {
+    /** array key that points to the edges and vertices */
+    private static final String JSON_ARRAY_KEY = "tx";
+    /** Connection to the HTTP REST endpoint */
+    private HttpURLConnection rexsterConn;
+    /** Output stream from the HTTP connection to the REST endpoint */
+    private BufferedWriter rexsterBufferedStream;
+    /** attribute used to keep the state of the element array status */
+    private boolean isFirstElement = true;
+    /** number of vertices before starting a new connection */
+    private int txsize;
+    /** number of vertexes of vertices sent */
+    private int txcounter = 0;
+    /** label of the vertex id field */
+    private String vlabel;
+    /** Back-off time delay in milliseconds */
+    private int backoffDelay = 0;
+    /** Back-off number of attempts */
+    private int backoffRetry = 0;
+
+    @Override
+    public void initialize(TaskAttemptContext context) throws IOException,
+      InterruptedException {
+
+      txsize = GIRAPH_REXSTER_OUTPUT_E_TXSIZE.get(getConf());
+      vlabel = GIRAPH_REXSTER_VLABEL.get(getConf());
+      backoffDelay = GIRAPH_REXSTER_BACKOFF_DELAY.get(getConf());
+      backoffRetry = GIRAPH_REXSTER_BACKOFF_RETRY.get(getConf());
+      startConnection();
+    }
+
+    @Override
+    public void close(TaskAttemptContext context)
+      throws IOException, InterruptedException {
+
+      stopConnection();
+    }
+
+    @Override
+    public void writeEdge(I srcId, V srcValue, Edge<I, E> edge)
+      throws IOException, InterruptedException {
+
+      if (txcounter == txsize) {
+        txcounter = 0;
+        isFirstElement = true;
+        stopConnection();
+        startConnection();
+      }
+
+      try {
+        JSONObject jsonEdge;
+        String suffix;
+
+        /* extract the JSON object of the vertex */
+        jsonEdge = getEdge(srcId, srcValue, edge);
+        /* determine the suffix to add the object into the JSON array */
+        if (isFirstElement) {
+          isFirstElement = false;
+          suffix = "";
+        } else {
+          suffix = ",";
+        }
+        rexsterBufferedStream.write(suffix + jsonEdge);
+        txcounter += 1;
+
+      } catch (JSONException e) {
+        throw new InterruptedException("Error writing the edge: " +
+                                       e.getMessage());
+      }
+    }
+
+    /**
+     * Start a new connection with the Rexster REST endpoint.
+     */
+    private void startConnection() throws IOException, InterruptedException {
+      rexsterConn = RexsterUtils.Edge.openOutputConnection(getConf());
+      rexsterBufferedStream = new BufferedWriter(
+          new OutputStreamWriter(rexsterConn.getOutputStream(),
+                                 Charset.forName("UTF-8")));
+      /* open the JSON container: is an object containing an array of
+         elements */
+      rexsterBufferedStream.write("{ ");
+      rexsterBufferedStream.write("\"vlabel\" : \"" + vlabel + "\",");
+      rexsterBufferedStream.write("\"delay\" : \"" + backoffDelay + "\",");
+      rexsterBufferedStream.write("\"retry\" : \"" + backoffRetry + "\",");
+      rexsterBufferedStream.write("\"" + JSON_ARRAY_KEY + "\"");
+      rexsterBufferedStream.write(" : [ ");
+    }
+
+    /**
+     * Stop a new connection with the Rexster REST endpoint. By default the
+     * JDK manages keep-alive so no particular code is sent in place for this
+     * aim.
+     */
+    private void stopConnection() throws IOException, InterruptedException {
+      /* close the JSON container */
+      rexsterBufferedStream.write(" ] }");
+      rexsterBufferedStream.flush();
+      rexsterBufferedStream.close();
+
+      /* check the response and in case of error signal the unsuccessful state
+         via exception */
+      RexsterUtils.Edge.handleResponse(rexsterConn);
+    }
+
+    /**
+     * Each edge needs to be transformed into a JSON object to be sent to the
+     * batch interface of Rexster.
+     *
+     * @param  srcId    source vertex ID of the edge
+     * @param  srcValue source vertex value of the edge
+     * @param  edge     edge to be transformed in JSON
+     * @return          JSON representation of the edge
+     */
+    protected JSONObject getEdge(I srcId, V srcValue, Edge<I, E> edge)
+      throws JSONException {
+
+      String outId = srcId.toString();
+      String inId = edge.getTargetVertexId().toString();
+      String value = edge.getValue().toString();
+      JSONObject jsonEdge = new JSONObject();
+      jsonEdge.accumulate("_outV", outId);
+      jsonEdge.accumulate("_inV",  inId);
+      jsonEdge.accumulate("value", value);
+
+      return jsonEdge;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterInputSplit.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterInputSplit.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterInputSplit.java
new file mode 100644
index 0000000..b6da8de
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterInputSplit.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io;
+
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapreduce.InputSplit;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * A InputSplit that spans a set of vertices. This code is taken from the
+ * Faunus project and was originally authored by Stephen Mallette.
+ */
+public class RexsterInputSplit extends InputSplit implements Writable {
+  /** End index for the Rexster paging */
+  private long end = 0;
+  /** Start index for the Rexster paging */
+  private long start = 0;
+
+  /**
+   * Default constructor.
+   */
+  public RexsterInputSplit() {
+  }
+
+  /**
+   * Overloaded constructor
+   * @param start   start of the paging provided by Rexster
+   * @param end     end of the paging provided by Rexster
+   */
+  public RexsterInputSplit(long start, long end) {
+    this.start = start;
+    this.end = end;
+  }
+
+  /**
+   * Stub function returning empty list of locations
+   * @return String[]     array of locations
+   * @throws IOException
+   */
+  public String[] getLocations() {
+    return new String[]{};
+  }
+
+  /**
+   * Get the start of the paging.
+   * @return long   start of the paging
+   */
+  public long getStart() {
+    return start;
+  }
+
+  /**
+   * Get the end of the paging.
+   * @return long   end of the paging
+   */
+  public long getEnd() {
+    return end;
+  }
+
+  /**
+   * Get the length of the paging
+   * @return long   length of the page
+   */
+  public long getLength() {
+    return end - start;
+  }
+
+  /**
+   *
+   * @param  input        data input from where to unserialize
+   * @throws IOException
+   */
+  public void readFields(DataInput input) throws IOException {
+    start = input.readLong();
+    end = input.readLong();
+  }
+
+  /**
+   *
+   * @param output        data output where to serialize
+   * @throws IOException
+   */
+  public void write(DataOutput output) throws IOException {
+    output.writeLong(start);
+    output.writeLong(end);
+  }
+
+  @Override
+  public String toString() {
+    return String.format("Split at [%s to %s]", this.start,
+                         this.end == Long.MAX_VALUE ? "END" : this.end - 1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexInputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexInputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexInputFormat.java
new file mode 100644
index 0000000..bee22f5
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexInputFormat.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io;
+
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_V_ESTIMATE;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_HOSTNAME;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.io.VertexInputFormat;
+import org.apache.giraph.io.VertexReader;
+import org.apache.giraph.rexster.utils.RexsterUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.io.WritableComparable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+/**
+ * Abstract class that users should subclass to use their own Rexster based
+ * vertex input format. This class was inspired by the Rexster Input format
+ * available in Faunus authored by Stephen Mallette.
+ *
+ * @param <I>
+ * @param <V>
+ * @param <E>
+ */
+@SuppressWarnings("rawtypes")
+public abstract class RexsterVertexInputFormat<I extends WritableComparable,
+  V extends Writable, E extends Writable>
+  extends VertexInputFormat<I, V, E> {
+
+  /** Class logger. */
+  private static final Logger LOG =
+      Logger.getLogger(RexsterVertexInputFormat.class);
+
+  /**
+   * @param conf configuration parameters
+   */
+  public void checkInputSpecs(Configuration conf) {
+    GiraphConfiguration gconf = new GiraphConfiguration(conf);
+
+    if (!gconf.hasEdgeInputFormat()) {
+      String err = "Rexster Input I/O requires " +
+                   "both Vertex- and EdgeInputFormat.";
+      LOG.error(err);
+      throw new RuntimeException(err);
+    }
+
+    String endpoint = GIRAPH_REXSTER_HOSTNAME.get(conf);
+    if (endpoint == null) {
+      throw new RuntimeException(GIRAPH_REXSTER_HOSTNAME.getKey() +
+                                 " is a mandatory parameter.");
+    }
+  }
+
+  /**
+   * Create a vertex reader for a given split. Guaranteed to have been
+   * configured with setConf() prior to use.  The framework will also call
+   * {@link VertexReader#initialize(InputSplit, TaskAttemptContext)} before
+   * the split is used.
+   *
+   * @param split the split to be read
+   * @param context the information about the task
+   * @return a new record reader
+   * @throws IOException
+   */
+  public abstract RexsterVertexReader createVertexReader(InputSplit split,
+    TaskAttemptContext context) throws IOException;
+
+  @Override
+  public List<InputSplit> getSplits(JobContext context, int minSplitCountHint)
+    throws IOException, InterruptedException {
+
+    return RexsterUtils.getSplits(context,
+                                  GIRAPH_REXSTER_V_ESTIMATE.get(getConf()));
+  }
+
+  /**
+   * Abstract class to be implemented by the user based on their specific
+   * vertex input. Easiest to ignore the key value separator and only use
+   * key instead.
+   */
+  protected abstract class RexsterVertexReader extends VertexReader<I, V, E> {
+
+    /** Input stream from the HTTP connection to the REST endpoint */
+    private BufferedReader rexsterBufferedStream;
+    /** JSON parser/tokenizer object */
+    private JSONTokener tokener;
+    /** start index of the Rexster paging */
+    private long splitStart;
+    /** end index of the Rexster paging */
+    private long splitEnd;
+    /** index to access the iterated vertices */
+    private long itemsIterated = 0;
+    /** current vertex */
+    private Vertex<I, V, E> vertex;
+    /** first call to the nextVertex fuction */
+    private boolean isFirstVertex;
+
+    @Override
+    public void initialize(InputSplit inputSplit, TaskAttemptContext context)
+      throws IOException, InterruptedException {
+
+      RexsterInputSplit rexsterInputSplit = (RexsterInputSplit) inputSplit;
+      splitEnd = rexsterInputSplit.getEnd();
+      splitStart = rexsterInputSplit.getStart();
+      rexsterBufferedStream = RexsterUtils.Vertex.openInputStream(getConf(),
+        splitStart, splitEnd);
+      tokener = RexsterUtils.parseJSONEnvelope(rexsterBufferedStream);
+      isFirstVertex = true;
+    }
+
+    @Override
+    public boolean nextVertex() throws IOException, InterruptedException {
+      try {
+        /* if the tokener was not set, no object is in fact available */
+        if (this.tokener == null) {
+          return false;
+        }
+
+        char c;
+        if (isFirstVertex) {
+          isFirstVertex = false;
+
+          c = this.tokener.nextClean();
+          if (c == RexsterUtils.END_ARRAY) {
+            return false;
+          }
+          tokener.back();
+        }
+
+        JSONObject obj = new JSONObject(this.tokener);
+        this.vertex = parseVertex(obj);
+
+        c = this.tokener.nextClean();
+        if (c == RexsterUtils.ARRAY_SEPARATOR) {
+          itemsIterated += 1;
+          return true;
+        } else if (c == RexsterUtils.END_ARRAY) {
+          return false;
+        } else {
+          LOG.error(String.format("Expected a '%c' at the end of the array",
+                                  RexsterUtils.END_ARRAY));
+          throw new InterruptedException(
+              String.format("Expected a '%c' at the end of the array",
+                            RexsterUtils.END_ARRAY));
+        }
+      } catch (JSONException e) {
+        throw new InterruptedException(e.toString());
+      }
+    }
+
+    @Override
+    public void close() throws IOException {
+      this.rexsterBufferedStream.close();
+    }
+
+    @Override
+    public float getProgress() throws IOException, InterruptedException {
+      float vestimated = GIRAPH_REXSTER_V_ESTIMATE.get(getConf());
+
+      if (this.splitStart == this.splitEnd) {
+        return 0.0f;
+      } else {
+        // assuming you got the estimate right this progress should be
+        // pretty close;
+        return Math.min(1.0f, this.itemsIterated / (float) vestimated);
+      }
+    }
+
+    @Override
+    public Vertex<I, V, E> getCurrentVertex()
+      throws IOException, InterruptedException {
+
+      return this.vertex;
+    }
+
+    /**
+     * Parser for a single vertex JSON object
+     *
+     * @param   jsonVertex vertex represented as JSON object
+     * @return  The vertex object represented by the JSON object
+     */
+    protected abstract Vertex<I, V, E> parseVertex(JSONObject jsonVertex)
+      throws JSONException;
+  }
+}


[3/4] GIRAPH-803

Posted by cl...@apache.org.
http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexOutputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexOutputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexOutputFormat.java
new file mode 100644
index 0000000..9af00e0
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/RexsterVertexOutputFormat.java
@@ -0,0 +1,382 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io;
+
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_OUTPUT_V_TXSIZE;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_OUTPUT_WAIT_TIMEOUT;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_VLABEL;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_HOSTNAME;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.nio.charset.Charset;
+import java.util.List;
+
+import org.apache.giraph.bsp.BspService;
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.io.VertexOutputFormat;
+import org.apache.giraph.io.VertexWriter;
+import org.apache.giraph.rexster.utils.RexsterUtils;
+import org.apache.giraph.zk.ZooKeeperExt;
+import org.apache.giraph.zk.ZooKeeperManager;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.io.WritableComparable;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.hadoop.mapreduce.OutputCommitter;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Abstract class that users should subclass to use their own Rexster based
+ * vertex onput format.
+ *
+ * @param <I>
+ * @param <V>
+ * @param <E>
+ */
+@SuppressWarnings("rawtypes")
+public class RexsterVertexOutputFormat<I extends WritableComparable,
+  V extends Writable, E extends Writable>
+  extends VertexOutputFormat<I, V, E> {
+
+  /** Class logger. */
+  private static final Logger LOG =
+      Logger.getLogger(RexsterVertexOutputFormat.class);
+
+  @Override
+  public RexsterVertexWriter
+  createVertexWriter(TaskAttemptContext context)
+    throws IOException, InterruptedException {
+
+    return new RexsterVertexWriter();
+  }
+
+  @Override
+  public void checkOutputSpecs(JobContext context)
+    throws IOException, InterruptedException {
+    GiraphConfiguration gconf =
+      new GiraphConfiguration(context.getConfiguration());
+    String msg = "Rexster OutputFormat usage requires both Edge and Vertex " +
+                 "OutputFormat's.";
+
+    if (!gconf.hasEdgeOutputFormat()) {
+      LOG.error(msg);
+      throw new InterruptedException(msg);
+    }
+
+    String endpoint = GIRAPH_REXSTER_HOSTNAME.get(gconf);
+    if (endpoint == null) {
+      throw new InterruptedException(GIRAPH_REXSTER_HOSTNAME.getKey() +
+                                     " is a mandatory parameter.");
+    }
+  }
+
+  @Override
+  public OutputCommitter getOutputCommitter(TaskAttemptContext context)
+    throws IOException, InterruptedException {
+
+    return new NullOutputCommitter();
+  }
+
+  /**
+   * Empty output commiter for hadoop.
+   */
+  private static class NullOutputCommitter extends OutputCommitter {
+    @Override
+    public void abortTask(TaskAttemptContext taskContext) { }
+
+    @Override
+    public void cleanupJob(JobContext jobContext) { }
+
+    @Override
+    public void commitTask(TaskAttemptContext taskContext) { }
+
+    @Override
+    public boolean needsTaskCommit(TaskAttemptContext taskContext) {
+      return false;
+    }
+
+    @Override
+    public void setupJob(JobContext jobContext) { }
+
+    @Override
+    public void setupTask(TaskAttemptContext taskContext) { }
+  }
+
+  /**
+   * Abstract class to be implemented by the user based on their specific
+   * vertex/edges output. Easiest to ignore the key value separator and only
+   * use key instead.
+   */
+  protected class RexsterVertexWriter extends VertexWriter<I, V, E>
+    implements Watcher {
+    /** barrier path */
+    private static final String BARRIER_PATH = "/_rexsterBarrier";
+    /** array key that points to the edges and vertices */
+    private static final String JSON_ARRAY_KEY = "tx";
+    /** Connection to the HTTP REST endpoint */
+    private HttpURLConnection rexsterConn;
+    /** Output stream from the HTTP connection to the REST endpoint */
+    private BufferedWriter rexsterBufferedStream;
+    /** attribute used to keep the state of the element array status */
+    private boolean isFirstElement = true;
+    /** ZooKeeper client object */
+    private ZooKeeperExt zk = null;
+    /** lock for management of the barrier */
+    private final Object lock = new Object();
+    /** number of vertices before starting a new connection */
+    private int txsize;
+    /** number of vertexes of vertices sent */
+    private int txcounter = 0;
+    /** label of the vertex id field */
+    private String vlabel;
+    /** vertex id */
+    private I vertexId;
+
+    @Override
+    public void initialize(TaskAttemptContext context)
+      throws IOException, InterruptedException {
+      ImmutableClassesGiraphConfiguration conf = getConf();
+
+      vlabel = GIRAPH_REXSTER_VLABEL.get(conf);
+      txsize = GIRAPH_REXSTER_OUTPUT_V_TXSIZE.get(conf);
+      startConnection();
+
+      /* set the barrier */
+      zk = new ZooKeeperExt(conf.getZookeeperList(),
+          conf.getZooKeeperSessionTimeout(), conf.getZookeeperOpsMaxAttempts(),
+          conf.getZookeeperOpsRetryWaitMsecs(), this, context);
+    }
+
+    @Override
+    public void close(TaskAttemptContext context)
+      throws IOException, InterruptedException {
+      /* close connection */
+      stopConnection();
+
+      /* deal with the barrier */
+      String id = context.getTaskAttemptID().toString();
+      String zkBasePath = ZooKeeperManager.getBasePath(getConf()) +
+        BspService.BASE_DIR + "/" +
+        getConf().get("mapred.job.id", "Unknown Job");
+      prepareBarrier(zkBasePath);
+      enterBarrier(zkBasePath, id);
+      checkBarrier(zkBasePath, context);
+    }
+
+    @Override
+    public void writeVertex(Vertex<I, V, E> vertex)
+      throws IOException, InterruptedException {
+
+      if (txcounter == txsize) {
+        txcounter = 0;
+        isFirstElement = true;
+        stopConnection();
+        startConnection();
+      }
+
+      try {
+        /* extract the JSON object of the vertex */
+        JSONObject jsonVertex = getVertex(vertex);
+        jsonVertex.accumulate("_type", "vertex");
+        jsonVertex.accumulate(vlabel, getVertexId().toString());
+        String suffix = ",";
+        if (isFirstElement) {
+          isFirstElement = false;
+          suffix = "";
+        }
+        rexsterBufferedStream.write(suffix + jsonVertex);
+        txcounter += 1;
+
+      } catch (JSONException e) {
+        throw new InterruptedException("Error writing the vertex: " +
+                                       e.getMessage());
+      }
+    }
+
+    @Override
+    public void process(WatchedEvent event) {
+      EventType type = event.getType();
+
+      if (type == EventType.NodeChildrenChanged) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("signal: number of children changed.");
+        }
+        synchronized (lock) {
+          lock.notify();
+        }
+      }
+    }
+
+    /**
+     * Prepare the root node if needed to create the root Rexster barrier znode
+     *
+     * @param  zkBasePath  base path for zookeeper
+     * @throws InterruptedException
+     */
+    private void prepareBarrier(String zkBasePath)
+      throws InterruptedException {
+      try {
+        zk.createExt(zkBasePath + BARRIER_PATH, null, Ids.OPEN_ACL_UNSAFE,
+          CreateMode.PERSISTENT, false);
+      } catch (KeeperException.NodeExistsException nee) {
+        if (LOG.isInfoEnabled()) {
+          LOG.info("rexster barrier znode already exists.");
+        }
+      } catch (KeeperException ke) {
+        throw new InterruptedException("RexsterVertexOutputFormat: " +
+            "error while creating the barrier: " + ke.getMessage());
+      }
+    }
+
+    /**
+     * Enter the Rexster barrier
+     *
+     * @param  zkBasePath  base path for zookeeper
+     * @param  id       value id used for the znode
+     * @throws InterruptedException
+     */
+    private void enterBarrier(String zkBasePath, String id)
+      throws InterruptedException {
+      try {
+        zk.createExt(zkBasePath + BARRIER_PATH + "/" + id, null,
+          Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, false);
+      } catch (KeeperException.NodeExistsException nee) {
+        if (LOG.isInfoEnabled()) {
+          LOG.info("rexster barrier znode already exists.");
+        }
+      } catch (KeeperException ke) {
+        throw new InterruptedException("RexsterVertexOutputFormat: " +
+            "error while creating the barrier: " + ke.getMessage());
+      }
+    }
+
+    /**
+     * Check the Rexster barrier to verify whether all the vertices have been
+     * saved. If so, the barrier can be left and it is possible to save the
+     * edges.
+     *
+     * @param  zkBasePath  base path for zookeeper
+     * @param  context  task attempt context
+     * @throws InterruptedException
+     */
+    private void checkBarrier(String zkBasePath,
+      TaskAttemptContext context) throws InterruptedException {
+      long workersNum = getConf().getMapTasks() - 1;
+      int timeout = GIRAPH_REXSTER_OUTPUT_WAIT_TIMEOUT.get(getConf());
+
+      try {
+        String barrierPath = zkBasePath + BARRIER_PATH;
+        while (true) {
+          List<String> list =
+            zk.getChildrenExt(barrierPath, true, false, false);
+
+          if (list.size() < workersNum) {
+            synchronized (lock) {
+              lock.wait(timeout);
+            }
+            context.progress();
+          } else {
+            return;
+          }
+        }
+      } catch (KeeperException ke) {
+        throw new InterruptedException("Error while checking the barrier:" +
+                                       ke.getMessage());
+      }
+    }
+
+    /**
+     * Start a new connection with the Rexster REST endpoint.
+     */
+    private void startConnection() throws IOException, InterruptedException {
+      rexsterConn = RexsterUtils.Vertex.openOutputConnection(getConf());
+      rexsterBufferedStream = new BufferedWriter(
+          new OutputStreamWriter(rexsterConn.getOutputStream(),
+                                 Charset.forName("UTF-8")));
+      /* open the JSON container: is an object containing an array of
+         elements */
+      rexsterBufferedStream.write("{ ");
+      rexsterBufferedStream.write("\"vlabel\" : \"" + vlabel + "\",");
+      rexsterBufferedStream.write("\"" + JSON_ARRAY_KEY + "\"");
+      rexsterBufferedStream.write(" : [ ");
+    }
+
+    /**
+     * Stop a new connection with the Rexster REST endpoint. By default the
+     * JDK manages keep-alive so no particular code is sent in place for this
+     * aim.
+     */
+    private void stopConnection() throws IOException, InterruptedException {
+      /* close the JSON container */
+      rexsterBufferedStream.write(" ] }");
+      rexsterBufferedStream.flush();
+      rexsterBufferedStream.close();
+
+      /* check the response and in case of error signal the unsuccessful state
+         via exception */
+      RexsterUtils.Vertex.handleResponse(rexsterConn);
+    }
+
+    /**
+     * Each vertex needs to be transformed into a JSON object to be sent to the
+     * batch interface of Rexster. This function does NOT need to implement any
+     * edge transformation since RexsterVertexWriter#getEdge is
+     * intended for such a task.
+     *
+     * @param  vertex   vertex to be transformed into JSON
+     * @return          JSON representation of the vertex
+     */
+    protected JSONObject getVertex(Vertex<I, V, E> vertex)
+      throws JSONException {
+
+      vertexId = vertex.getId();
+
+      String value = vertex.getValue().toString();
+      JSONObject jsonVertex = new JSONObject();
+      jsonVertex.accumulate("value", value);
+
+      return jsonVertex;
+    }
+
+    /**
+     * For compatibility reasons, the id of the vertex needs to be accumulated
+     * in the vertex object using the defined vlabel, hence we provide a
+     * different function to get the vertex id to keep this compatibility
+     * management indipendent from the user implementation.
+     *
+     * @return vertex id object
+     */
+    protected I getVertexId() {
+      return vertexId;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleEdgeOutputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleEdgeOutputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleEdgeOutputFormat.java
new file mode 100644
index 0000000..80911ff
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleEdgeOutputFormat.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.rexster.io.RexsterEdgeOutputFormat;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Edge Output Format for Long ID's, Double Vertex values and
+ * Double edge values.
+ */
+public class RexsterLongDoubleDoubleEdgeOutputFormat
+  extends RexsterEdgeOutputFormat<LongWritable, DoubleWritable,
+          DoubleWritable> {
+
+  @Override
+  public RexsterEdgeWriter createEdgeWriter(
+      TaskAttemptContext context) throws IOException,
+      InterruptedException {
+
+    return new RexsterLongDoubleDoubleEdgeWriter();
+  }
+
+  /**
+   * Rexster edge writer.
+   */
+  protected class RexsterLongDoubleDoubleEdgeWriter
+    extends RexsterEdgeWriter {
+
+    @Override
+    protected JSONObject getEdge(LongWritable srcId, DoubleWritable srcValue,
+      Edge<LongWritable, DoubleWritable> edge) throws JSONException {
+
+      long outId = srcId.get();
+      long inId = edge.getTargetVertexId().get();
+      double value = edge.getValue().get();
+      JSONObject jsonEdge = new JSONObject();
+      jsonEdge.accumulate("_outV", outId);
+      jsonEdge.accumulate("_inV",  inId);
+      jsonEdge.accumulate("value", value);
+
+      return jsonEdge;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexInputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexInputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexInputFormat.java
new file mode 100644
index 0000000..7aa643a
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexInputFormat.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.rexster.io.RexsterVertexInputFormat;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Edge Input Format for Long vertex ID's and Double edge values
+ */
+public class RexsterLongDoubleDoubleVertexInputFormat
+  extends RexsterVertexInputFormat<LongWritable, DoubleWritable,
+          DoubleWritable> {
+
+  @Override
+  public RexsterVertexReader createVertexReader(
+    InputSplit split, TaskAttemptContext context) throws IOException {
+
+    return new RexsterLongDoubleDoubleVertexReader();
+  }
+
+  /**
+   * Rexster vertex reader
+   */
+  protected class RexsterLongDoubleDoubleVertexReader
+    extends RexsterVertexReader {
+
+    @Override
+    protected Vertex<LongWritable, DoubleWritable, DoubleWritable> parseVertex(
+      JSONObject jsonVertex) throws JSONException {
+
+      /* create the actual vertex */
+      Vertex<LongWritable, DoubleWritable, DoubleWritable> vertex =
+        getConf().createVertex();
+
+      Long id;
+      try {
+        id = jsonVertex.getLong("_id");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        String idString = jsonVertex.getString("_id");
+        String[] splits = idString.split(":");
+        id = Long.parseLong(splits[1]);
+      }
+
+      Double value;
+      try {
+        value = jsonVertex.getDouble("value");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        value = new Double(0);
+      }
+      vertex.initialize(new LongWritable(id), new DoubleWritable(value));
+      return vertex;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexOutputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexOutputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexOutputFormat.java
new file mode 100644
index 0000000..a1a6cc5
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleDoubleVertexOutputFormat.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.rexster.io.RexsterVertexOutputFormat;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Vertex Output Format for Long ID's, Double Vertex values and
+ * Double edge values.
+ */
+public class RexsterLongDoubleDoubleVertexOutputFormat
+  extends RexsterVertexOutputFormat<LongWritable, DoubleWritable,
+          DoubleWritable> {
+
+  @Override
+  public RexsterVertexWriter createVertexWriter(
+      TaskAttemptContext context) throws IOException,
+      InterruptedException {
+
+    return new RexsterLongDoubleDoubleVertexWriter();
+  }
+
+  /**
+   * Rexster vertex writer.
+   */
+  protected class RexsterLongDoubleDoubleVertexWriter
+    extends RexsterVertexWriter {
+
+    /** current vertex ID */
+    private LongWritable vertexId;
+
+    @Override
+    protected JSONObject getVertex(
+      Vertex<LongWritable, DoubleWritable, DoubleWritable> vertex)
+      throws JSONException {
+
+      vertexId = vertex.getId();
+
+      double value = vertex.getValue().get();
+      JSONObject jsonVertex = new JSONObject();
+      jsonVertex.accumulate("value", value);
+
+      return jsonVertex;
+    }
+
+    @Override
+    protected LongWritable getVertexId() {
+      return vertexId;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleEdgeInputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleEdgeInputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleEdgeInputFormat.java
new file mode 100644
index 0000000..9974c28
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleEdgeInputFormat.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.edge.EdgeFactory;
+import org.apache.giraph.rexster.io.RexsterEdgeInputFormat;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Edge Input Format for Long vertex ID's and Double edge values
+ */
+public class RexsterLongDoubleEdgeInputFormat
+  extends RexsterEdgeInputFormat<LongWritable, DoubleWritable> {
+
+  @Override
+  public RexsterEdgeReader createEdgeReader(
+      InputSplit split, TaskAttemptContext context) throws IOException {
+
+    return new RexsterLongDoubleEdgeReader();
+  }
+
+  /**
+   * Rexster edge reader
+   */
+  protected class RexsterLongDoubleEdgeReader extends RexsterEdgeReader {
+
+    /** source vertex of the edge */
+    private LongWritable sourceId;
+
+    @Override
+    public LongWritable getCurrentSourceId()
+      throws IOException, InterruptedException {
+
+      return this.sourceId;
+    }
+
+    @Override
+    protected Edge<LongWritable, DoubleWritable> parseEdge(JSONObject jsonEdge)
+      throws JSONException {
+
+      Long value = jsonEdge.getLong("value");
+      Long dest;
+      try {
+        dest = jsonEdge.getLong("_outV");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        String idString = jsonEdge.getString("_outV");
+        String[] splits = idString.split(":");
+        dest = Long.parseLong(splits[1]);
+      }
+      Edge<LongWritable, DoubleWritable> edge =
+        EdgeFactory.create(new LongWritable(dest), new DoubleWritable(value));
+
+      Long sid;
+      try {
+        sid = jsonEdge.getLong("_inV");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        String sidString = jsonEdge.getString("_inV");
+        String[] splits = sidString.split(":");
+        sid = Long.parseLong(splits[1]);
+      }
+      this.sourceId = new LongWritable(sid);
+      return edge;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatEdgeOutputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatEdgeOutputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatEdgeOutputFormat.java
new file mode 100644
index 0000000..3637837
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatEdgeOutputFormat.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.rexster.io.RexsterEdgeOutputFormat;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Edge Output Format for Long ID's, Double Vertex values and
+ * Float edge values.
+ */
+public class RexsterLongDoubleFloatEdgeOutputFormat
+  extends RexsterEdgeOutputFormat<LongWritable, DoubleWritable,
+          FloatWritable> {
+
+  @Override
+  public RexsterEdgeWriter createEdgeWriter(
+      TaskAttemptContext context) throws IOException,
+      InterruptedException {
+
+    return new RexsterLongDoubleFloatEdgeWriter();
+  }
+
+  /**
+   * Rexster edge writer.
+   */
+  protected class RexsterLongDoubleFloatEdgeWriter
+    extends RexsterEdgeWriter {
+
+    @Override
+    protected JSONObject getEdge(LongWritable srcId, DoubleWritable srcValue,
+      Edge<LongWritable, FloatWritable> edge) throws JSONException {
+
+      long outId = srcId.get();
+      long inId = edge.getTargetVertexId().get();
+      float value = edge.getValue().get();
+      JSONObject jsonEdge = new JSONObject();
+      jsonEdge.accumulate("_outV", outId);
+      jsonEdge.accumulate("_inV",  inId);
+      jsonEdge.accumulate("value", value);
+
+      return jsonEdge;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexInputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexInputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexInputFormat.java
new file mode 100644
index 0000000..cbd78ce
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexInputFormat.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.rexster.io.RexsterVertexInputFormat;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Edge Input Format for Long vertex ID's and Float edge values
+ */
+public class RexsterLongDoubleFloatVertexInputFormat
+  extends RexsterVertexInputFormat<LongWritable, DoubleWritable,
+          FloatWritable> {
+
+  @Override
+  public RexsterVertexReader createVertexReader(
+    InputSplit split, TaskAttemptContext context) throws IOException {
+
+    return new RexsterLongDoubleFloatVertexReader();
+  }
+
+  /**
+   * Rexster vertex reader
+   */
+  protected class RexsterLongDoubleFloatVertexReader
+    extends RexsterVertexReader {
+
+    @Override
+    protected Vertex<LongWritable, DoubleWritable, FloatWritable> parseVertex(
+      JSONObject jsonVertex) throws JSONException {
+
+      /* create the actual vertex */
+      Vertex<LongWritable, DoubleWritable, FloatWritable> vertex =
+        getConf().createVertex();
+
+      Long id;
+      try {
+        id = jsonVertex.getLong("_id");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        String idString = jsonVertex.getString("_id");
+        String[] splits = idString.split(":");
+        id = Long.parseLong(splits[1]);
+      }
+
+      Double value;
+      try {
+        value = jsonVertex.getDouble("value");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        value = new Double(0);
+      }
+
+      vertex.initialize(new LongWritable(id), new DoubleWritable(value));
+      return vertex;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexOutputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexOutputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexOutputFormat.java
new file mode 100644
index 0000000..2210887
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongDoubleFloatVertexOutputFormat.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.rexster.io.RexsterVertexOutputFormat;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Vertex Output Format for Long ID's, Double Vertex values and
+ * Float edge values.
+ */
+public class RexsterLongDoubleFloatVertexOutputFormat
+  extends RexsterVertexOutputFormat<LongWritable, DoubleWritable,
+          FloatWritable> {
+
+  @Override
+  public RexsterVertexWriter createVertexWriter(
+      TaskAttemptContext context) throws IOException,
+      InterruptedException {
+
+    return new RexsterLongDoubleFloatVertexWriter();
+  }
+
+  /**
+   * Rexster vertex writer.
+   */
+  protected class RexsterLongDoubleFloatVertexWriter
+    extends RexsterVertexWriter {
+
+    /** current vertex ID */
+    private LongWritable vertexId;
+
+    @Override
+    protected JSONObject getVertex(
+      Vertex<LongWritable, DoubleWritable, FloatWritable> vertex)
+      throws JSONException {
+
+      vertexId = vertex.getId();
+
+      double value = vertex.getValue().get();
+      JSONObject jsonVertex = new JSONObject();
+      jsonVertex.accumulate("value", value);
+
+      return jsonVertex;
+    }
+
+    @Override
+    protected LongWritable getVertexId() {
+      return vertexId;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongFloatEdgeInputFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongFloatEdgeInputFormat.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongFloatEdgeInputFormat.java
new file mode 100644
index 0000000..3b13922
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/RexsterLongFloatEdgeInputFormat.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import java.io.IOException;
+
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.edge.EdgeFactory;
+import org.apache.giraph.rexster.io.RexsterEdgeInputFormat;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rexster Edge Input Format for Long vertex ID's and Float edge values
+ */
+public class RexsterLongFloatEdgeInputFormat
+  extends RexsterEdgeInputFormat<LongWritable, FloatWritable> {
+
+  @Override
+  public RexsterEdgeReader createEdgeReader(
+      InputSplit split, TaskAttemptContext context) throws IOException {
+
+    return new RexsterLongFloatEdgeReader();
+  }
+
+  /**
+   * Rexster edge reader
+   */
+  protected class RexsterLongFloatEdgeReader extends RexsterEdgeReader {
+
+    /** source vertex of the edge */
+    private LongWritable sourceId;
+
+    @Override
+    public LongWritable getCurrentSourceId()
+      throws IOException, InterruptedException {
+
+      return this.sourceId;
+    }
+
+    @Override
+    protected Edge<LongWritable, FloatWritable> parseEdge(JSONObject jsonEdge)
+      throws JSONException {
+
+      Long value = jsonEdge.getLong("value");
+      Long dest;
+      try {
+        dest = jsonEdge.getLong("_outV");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        String idString = jsonEdge.getString("_outV");
+        String[] splits = idString.split(":");
+        dest = Long.parseLong(splits[1]);
+      }
+      Edge<LongWritable, FloatWritable> edge =
+        EdgeFactory.create(new LongWritable(dest), new FloatWritable(value));
+
+      Long sid;
+      try {
+        sid = jsonEdge.getLong("_inV");
+      } catch (JSONException ex) {
+        /* OrientDB compatibility; try to transform it as long */
+        String sidString = jsonEdge.getString("_inV");
+        String[] splits = sidString.split(":");
+        sid = Long.parseLong(splits[1]);
+      }
+      this.sourceId = new LongWritable(sid);
+      return edge;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/package-info.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/package-info.java
new file mode 100644
index 0000000..b5ae44f
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/formats/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Package of reusable Input/Output formats for Rexster in Giraph.
+ */
+package org.apache.giraph.rexster.io.formats;

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/package-info.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/package-info.java
new file mode 100644
index 0000000..bbd5a7f
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/io/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Package of reusable Input/Output formats for Rexster in Giraph.
+ */
+package org.apache.giraph.rexster.io;

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/RexsterUtils.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/RexsterUtils.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/RexsterUtils.java
new file mode 100644
index 0000000..a3d6a96
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/RexsterUtils.java
@@ -0,0 +1,486 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.utils;
+
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_GREMLIN_E_SCRIPT;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_GREMLIN_V_SCRIPT;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_HOSTNAME;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_INPUT_GRAPH;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_OUTPUT_GRAPH;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_PASSWORD;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_PORT;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_USERNAME;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_USES_SSL;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
+import org.apache.giraph.rexster.io.RexsterInputSplit;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+/**
+ * Utility functions for the Rexster REST interface
+ */
+@SuppressWarnings("rawtypes")
+public abstract class RexsterUtils {
+  /** start object symbol for JSON */
+  public static final char KEY_VALUE_SEPARATOR = ':';
+  /** start object symbol for JSON */
+  public static final char START_OBJECT = '{';
+  /** end object symbol for JSON */
+  public static final char END_OBJECT = '}';
+  /** start array symbol for JSON */
+  public static final char START_ARRAY = '[';
+  /** end array symbol for JSON */
+  public static final char END_ARRAY = ']';
+  /** array elements separator symbol for JSON */
+  public static final char ARRAY_SEPARATOR = ',';
+  /** Class logger. */
+  private static final Logger LOG = Logger.getLogger(RexsterUtils.class);
+
+  /**
+   * The default constructor is set to be private by default so that the
+   * class is not instantiated.
+   */
+  private RexsterUtils() { /* private constructor */ }
+
+  /**
+   * Parse all the vertices from the JSON retreived from Rexster. Inspired
+   * by the implementation of the JSONObject class.
+   *
+   * @param  br           buffer over the HTTP response content
+   * @return JSONTokener  tokener over the HTTP JSON. Null in case the results
+   *                      array is empty.
+   */
+  public static JSONTokener parseJSONEnvelope(BufferedReader br)
+    throws InterruptedException {
+
+    JSONTokener tokener = null;
+
+    try {
+      tokener = new JSONTokener(br);
+      /* check that the JSON is well-formed by starting with a '{' */
+      if (tokener.nextClean() != START_OBJECT) {
+        LOG.error(String.format("A JSONObject text must begin with '%c'",
+                  START_OBJECT));
+      }
+
+      /* loop on the whole array */
+      char c = '\0';
+      String key = null;
+      for (;;) {
+        c = tokener.nextClean();
+        switch (c) {
+        case 0:
+          LOG.error(String.format("A JSONObject text must end with '%c'",
+                    END_OBJECT));
+          break;
+        case END_OBJECT:
+          return tokener;
+        default:
+          tokener.back();
+          key = tokener.nextValue().toString();
+        }
+
+        c = tokener.nextClean();
+
+        if (c != KEY_VALUE_SEPARATOR) {
+          LOG.error(String.format("Expected a %c after a key", c));
+        }
+
+        if (key != null && !key.equals("results")) {
+          tokener.nextValue();
+        } else {
+          /* starting array */
+          c = tokener.nextClean();
+          if (c != START_ARRAY) {
+            LOG.error("'results' is expected to be an array");
+          }
+
+          /* check if the array is emty. If so, return null to signal that
+             no objects are available in the array, otherwise return the
+             tokener. */
+          c = tokener.nextClean();
+          if (c == END_ARRAY) {
+            return null;
+          } else {
+            tokener.back();
+            return tokener;
+          }
+        }
+
+        switch (tokener.nextClean()) {
+        case ';':
+        case ',':
+          if (tokener.nextClean() == '}') {
+            return tokener;
+          }
+          tokener.back();
+          break;
+        case '}':
+          return tokener;
+        default:
+          LOG.error("Expected a ',' or '}'");
+        }
+      }
+
+    } catch (JSONException e) {
+      LOG.error("Unable to parse the JSON with the vertices.\n" +
+                e.getMessage());
+      throw new InterruptedException(e.toString());
+    }
+  }
+
+  /**
+   * Splitter used by both Vertex and Edge Input Format.
+   *
+   * @param  context     The job context
+   * @param  estimation  Number of estimated objects
+   * @return splits to be generated to read the input
+   */
+  public static List<InputSplit> getSplits(JobContext context,
+    long estimation) throws IOException, InterruptedException {
+
+    int chunks = context.getConfiguration().getInt("mapred.map.tasks", 1);
+    long chunkSize = estimation / chunks;
+    List<InputSplit> splits = new ArrayList<InputSplit>();
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(String.format("Estimated objects: %d", estimation));
+      LOG.debug(String.format("Number of chunks: %d", chunks));
+    }
+
+    for (int i = 0; i < chunks; ++i) {
+      long start = i * chunkSize;
+      long end =
+        ((i + 1) == chunks) ? Long.MAX_VALUE : (i * chunkSize) + chunkSize;
+      RexsterInputSplit split = new RexsterInputSplit(start, end);
+      splits.add(split);
+
+      if (LOG.isDebugEnabled()) {
+        LOG.debug(String.format("Chunk: start %d; end %d;", start, end));
+        LOG.debug(String.format("Chunk: size %d;", chunkSize));
+        LOG.debug(split);
+      }
+    }
+
+    return splits;
+  }
+
+  /**
+   * Opens an HTTP connection to the specified Rexster server.
+   *
+   * @param   conf            giraph configuration
+   * @param   start           start index of the Rexster page split
+   * @param   end             end index of the Rexster page split
+   * @param   type            stream type (vertices or edges) needed for the
+   *                          REST Url
+   * @param   gremlinScript   gremlin script. If set to null, will be ignored.
+   * @return  BufferedReader  the object used to retrieve the HTTP response
+   *                          content
+   */
+  // CHECKSTYLE: stop IllegalCatch
+  public static BufferedReader openInputStream(
+    ImmutableClassesGiraphConfiguration conf,
+    long start, long end, String type, String gremlinScript)
+    throws InterruptedException {
+
+    String uriScriptFormat =
+      "/graphs/%s/tp/gremlin?script=%s" +
+      "&rexster.offset.start=%s&rexster.offset.end=%s";
+    String uriFormat =
+      "/graphs/%s/tp/giraph/%s/" +
+      "?rexster.offset.start=%s&rexster.offset.end=%s";
+    String endpoint = GIRAPH_REXSTER_HOSTNAME.get(conf);
+
+    try {
+      boolean isSsl = GIRAPH_REXSTER_USES_SSL.get(conf);
+      int port = GIRAPH_REXSTER_PORT.get(conf);
+      String graph = GIRAPH_REXSTER_INPUT_GRAPH.get(conf);
+      URL url;
+      if (gremlinScript != null && !gremlinScript.isEmpty()) {
+        url = new URL(isSsl ? "https" : "http", endpoint, port,
+                      String.format(uriScriptFormat, graph, gremlinScript,
+                                    start, end));
+      } else {
+        url = new URL(isSsl ? "https" : "http", endpoint, port,
+                      String.format(uriFormat, graph, type, start, end));
+      }
+
+      LOG.info(url);
+
+      String username = GIRAPH_REXSTER_USERNAME.get(conf);
+      String password = GIRAPH_REXSTER_PASSWORD.get(conf);
+      String auth = getHTTPAuthString(username, password);
+
+      HttpURLConnection connection = createConnection(url, "GET", auth);
+      connection.setRequestProperty("Content-Type",
+        "application/json; charset=UTF-8");
+      connection.setDoInput(true);
+      connection.setDoOutput(false);
+      RexsterUtils.handleResponse(connection, type);
+
+      InputStream is  = connection.getInputStream();
+      InputStreamReader isr = new InputStreamReader(is,
+          Charset.forName("UTF-8"));
+      return new BufferedReader(isr);
+    } catch (Exception e) {
+      throw new InterruptedException(e.getMessage());
+    }
+  }
+  // CHECKSTYLE: resume IllegalCatch
+
+  /**
+   * Opens an HTTP connection to the specified Rexster server.
+   *
+   * @param conf giraph configuration
+   * @param type either edge or vertex
+   * @return  the object used to populate the HTTP response content
+   */
+  // CHECKSTYLE: stop IllegalCatch
+  public static HttpURLConnection openOutputConnection(
+    ImmutableClassesGiraphConfiguration conf, String type)
+    throws InterruptedException {
+
+    String uriFormat = "/graphs/%s/tp/giraph/%s/";
+    String endpoint = GIRAPH_REXSTER_HOSTNAME.get(conf);
+    boolean isSsl = GIRAPH_REXSTER_USES_SSL.get(conf);
+    int port = GIRAPH_REXSTER_PORT.get(conf);
+    String graph = GIRAPH_REXSTER_OUTPUT_GRAPH.get(conf);
+
+    try {
+      URL url = new URL(isSsl ? "https" : "http", endpoint, port,
+                        String.format(uriFormat, graph, type));
+      LOG.info(url);
+
+      String username = GIRAPH_REXSTER_USERNAME.get(conf);
+      String password = GIRAPH_REXSTER_PASSWORD.get(conf);
+      String auth = getHTTPAuthString(username, password);
+
+      HttpURLConnection connection = createConnection(url, "POST", auth);
+      connection.setRequestProperty("Content-Type",
+                                    "application/json; cherset=UTF-8");
+      connection.setDoInput(true);
+      connection.setDoOutput(true);
+      return connection;
+    } catch (Exception e) {
+      throw new InterruptedException(e.getMessage());
+    }
+  }
+  // CHECKSTYLE: resume IllegalCatch
+
+  /**
+   * Creates a new HTTP connection to the specified server.
+   *
+   * @param   url         URI to connec to
+   * @param   method      method used for the HTTP request
+   * @param   authValue   authetication value if available
+   * @return  a new HTTP connection
+   */
+  private static HttpURLConnection createConnection(final URL url,
+    final String method, final String authValue) throws Exception {
+
+    final HttpURLConnection connection =
+      (HttpURLConnection) url.openConnection();
+
+    connection.setConnectTimeout(0);
+    connection.setReadTimeout(0);
+    connection.setRequestMethod(method);
+    if (authValue != null) {
+      connection.setRequestProperty("Authorization", authValue);
+    }
+
+    return connection;
+  }
+
+  /**
+   * Utility to handle the output response in case of errors.
+   *
+   * @param conn connection to the Rexster Interface
+   * @param type type of data saved (vertices or edges)
+   */
+  private static void handleResponse(HttpURLConnection conn, String type)
+    throws IOException, InterruptedException {
+
+    if (conn.getResponseCode() != 200) {
+      InputStream is = conn.getErrorStream();
+      BufferedReader rd =
+        new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
+
+      JSONObject obj = new JSONObject(rd);
+      StringBuffer sb = new StringBuffer("Error occured while saving " +
+                                         type + ";");
+      String aux;
+      while ((aux = rd.readLine()) != null) {
+        sb.append(aux);
+      }
+      sb.append(obj);
+
+      /*
+      try {
+        LOG.info("--> " + obj);
+        String message = obj.getString("message");
+        sb.append(" ");
+        sb.append(message);
+      } catch (JSONException e) {
+        LOG.error("Unable to extract the error message.");
+      }
+      */
+      rd.close();
+
+      throw new InterruptedException(sb.toString());
+    }
+  }
+
+  /**
+   * Specific Rexster utility functions for vertices
+   */
+  public static class Vertex {
+    /**
+     * Empty private constructor. This class should not be instantiated.
+     */
+    private Vertex() { /* private constructor */ }
+
+    /**
+     * Opens an HTTP connection to the specified Rexster server for vertices.
+     *
+     * @param   conf            giraph configuration
+     * @param   start           start index of the Rexster page split
+     * @param   end             end index of the Rexster page split
+     * @return  BufferedReader  the object used to retrieve the HTTP response
+     */
+    public static BufferedReader openInputStream(
+      ImmutableClassesGiraphConfiguration conf, long start, long end)
+      throws InterruptedException {
+
+      String gremlinScript = GIRAPH_REXSTER_GREMLIN_V_SCRIPT.get(conf);
+      return RexsterUtils.openInputStream(conf, start, end, "vertices",
+                                          gremlinScript);
+    }
+
+    /**
+     * Opens an HTTP connection to the specified Rexster server for vertices.
+     *
+     * @param conf giraph configuration
+     * @return  the object used to populate the HTTP response content
+     */
+    public static HttpURLConnection openOutputConnection(
+      ImmutableClassesGiraphConfiguration conf)
+      throws InterruptedException {
+
+      return RexsterUtils.openOutputConnection(conf, "vertices");
+    }
+
+    /**
+     * Utility to handle the output response in case of errors.
+     *
+     * @param conn connection to the Rexster Interface
+     */
+    public static void handleResponse(HttpURLConnection conn)
+      throws IOException, InterruptedException {
+
+      RexsterUtils.handleResponse(conn, "vertices");
+    }
+  }
+
+  /**
+   * Specific Rexster utility functions for edges
+   */
+  public static class Edge {
+    /**
+     * Empty private constructor. This class should not be instantiated.
+     */
+    private Edge() { /* private constructor */ }
+
+    /**
+     * Opens an HTTP connection to the specified Rexster server for edges.
+     *
+     * @param   conf            giraph configuration
+     * @param   start           start index of the Rexster page split
+     * @param   end             end index of the Rexster page split
+     * @return  BufferedReader  the object used to retrieve the HTTP response
+     */
+    public static BufferedReader openInputStream(
+      ImmutableClassesGiraphConfiguration conf, long start, long end)
+      throws InterruptedException {
+
+      String gremlinScript = GIRAPH_REXSTER_GREMLIN_E_SCRIPT.get(conf);
+      return RexsterUtils.openInputStream(conf, start, end, "edges",
+                                          gremlinScript);
+    }
+
+    /**
+     * Opens an HTTP connection to the specified Rexster server for edges.
+     *
+     * @param conf giraph configuration
+     * @return  the object used to populate the HTTP response content
+     */
+    public static HttpURLConnection openOutputConnection(
+      ImmutableClassesGiraphConfiguration conf)
+      throws InterruptedException {
+
+      return RexsterUtils.openOutputConnection(conf, "edges");
+    }
+
+    /**
+     * Utility to handle the output response in case of errors.
+     *
+     * @param conn connection to the Rexster Interface
+     */
+    public static void handleResponse(HttpURLConnection conn)
+      throws IOException, InterruptedException {
+
+      RexsterUtils.handleResponse(conn, "edges");
+    }
+  }
+
+  /**
+   * Provide the Authentication string used for the HTTP connection with
+   * Rexster.
+   *
+   * @param  username   username to connect to HTTP
+   * @param  password   password to connect to HTTP
+   * @return String     the authentication string
+   */
+  private static String getHTTPAuthString(String username,
+    String password) {
+
+    if (username.isEmpty()) {
+      return null;
+    } else {
+      return "Basic " +
+             Base64.encodeBase64URLSafeString(
+               (username + ":" + password).getBytes(Charset.forName("UTF-8")));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/package-info.java b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/package-info.java
new file mode 100644
index 0000000..3f6810f
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/main/java/org/apache/giraph/rexster/utils/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Package of reusable utils for Rexster in Giraph.
+ */
+package org.apache.giraph.rexster.utils;

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/java/org/apache/giraph/rexster/io/formats/TestRexsterLongDoubleFloatIOFormat.java
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/java/org/apache/giraph/rexster/io/formats/TestRexsterLongDoubleFloatIOFormat.java b/giraph-rexster/giraph-rexster-io/src/test/java/org/apache/giraph/rexster/io/formats/TestRexsterLongDoubleFloatIOFormat.java
new file mode 100644
index 0000000..5008608
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/java/org/apache/giraph/rexster/io/formats/TestRexsterLongDoubleFloatIOFormat.java
@@ -0,0 +1,519 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.giraph.rexster.io.formats;
+
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_GREMLIN_E_SCRIPT;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_GREMLIN_V_SCRIPT;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_HOSTNAME;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_INPUT_GRAPH;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_OUTPUT_GRAPH;
+import static org.apache.giraph.rexster.conf.GiraphRexsterConstants.GIRAPH_REXSTER_PORT;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.io.FileUtils;
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.graph.BasicComputation;
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.io.formats.JsonLongDoubleFloatDoubleVertexInputFormat;
+import org.apache.giraph.io.formats.JsonLongDoubleFloatDoubleVertexOutputFormat;
+import org.apache.giraph.utils.InternalVertexRunner;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import com.tinkerpop.rexster.Tokens;
+import com.tinkerpop.rexster.protocol.EngineController;
+import com.tinkerpop.rexster.server.HttpRexsterServer;
+import com.tinkerpop.rexster.server.RexsterApplication;
+import com.tinkerpop.rexster.server.RexsterServer;
+import com.tinkerpop.rexster.server.XmlRexsterApplication;
+
+/**
+ * This test suit is intended to extensively test Rexster I/O Format
+ * together with the Kibble for such a goal.
+ */
+public class TestRexsterLongDoubleFloatIOFormat {
+  /** temporary directory */
+  protected static final String TMP_DIR = "/tmp/";
+  /** input JSON extension */
+  protected static final String REXSTER_CONF = "rexster.xml";
+  /** string databases */
+  protected static final String DATABASES[] = { "tgdb", "neodb", "orientdb" };
+  /** string database (empty one) */
+  protected static final String EMPTYDB = "emptydb";
+  /** Rexster server instance */
+  protected static RexsterServer server;
+
+  @BeforeClass
+  public static void initialSetup() throws Exception {
+    startRexsterServer();
+    insertDbData();
+  }
+
+  @AfterClass
+  static public void finalTearDown() throws Exception {
+    stopRexsterServer();
+    deleteDbs();
+  }
+
+  @Test
+  public void testEmptyDbInput() throws Exception {
+    testDbInput(EMPTYDB, true, false);
+  }
+
+  @Ignore("Fails due to maven dependecy conflicts.")
+  @Test
+  public void testEmptyDbInputGremlin() throws Exception {
+    testDbInput(EMPTYDB, true, true);
+  }
+
+  @Test
+  public void testTgDbInput() throws Exception {
+    testDbInput(DATABASES[0], false, false);
+  }
+
+  @Ignore("Fails due to maven dependecy conflicts.")
+  @Test
+  public void testTgDbInputGremlin() throws Exception {
+    testDbInput(DATABASES[0], false, true);
+  }
+
+  @Test
+  public void testNeoDbInput() throws Exception {
+    testDbInput(DATABASES[1], false, false);
+  }
+
+  @Ignore("Fails due to maven dependecy conflicts.")
+  @Test
+  public void testNeoDbInputGremlin() throws Exception {
+    testDbInput(DATABASES[1], false, true);
+  }
+
+  @Test
+  public void testOrientDbInput() throws Exception {
+    testDbInput(DATABASES[2], false, false);
+  }
+
+  @Ignore("Fails due to maven dependecy conflicts.")
+  @Test
+  public void testOrientDbInputGremlin() throws Exception {
+    testDbInput(DATABASES[2], false, true);
+  }
+
+  @Test
+  public void testTgDbOutput() throws Exception {
+    testDbOutput("empty" + DATABASES[0]);
+  }
+
+  @Test
+  public void testNeoDbOutput() throws Exception {
+    testDbOutput("empty" + DATABASES[1]);
+  }
+
+  @Test
+  public void testOrientDbOutput() throws Exception {
+    testDbOutput("empty" + DATABASES[2]);
+  }
+
+  private void testDbInput(String name, boolean isEmpty, boolean isGramlin)
+    throws Exception {
+
+    GiraphConfiguration conf = new GiraphConfiguration();
+    GIRAPH_REXSTER_HOSTNAME.set(conf, "127.0.0.1");
+    GIRAPH_REXSTER_PORT.set(conf, 18182);
+    GIRAPH_REXSTER_INPUT_GRAPH.set(conf, name);
+    if (isGramlin) {
+      GIRAPH_REXSTER_GREMLIN_V_SCRIPT.set(conf, "g.V");
+      GIRAPH_REXSTER_GREMLIN_E_SCRIPT.set(conf, "g.E");
+    }
+    conf.setComputationClass(EmptyComputation.class);
+    conf.setVertexInputFormatClass(
+        RexsterLongDoubleFloatVertexInputFormat.class);
+    conf.setEdgeInputFormatClass(RexsterLongFloatEdgeInputFormat.class);
+    conf.setVertexOutputFormatClass(
+        JsonLongDoubleFloatDoubleVertexOutputFormat.class);
+
+    Iterable<String> results = InternalVertexRunner.run(conf, new String[0],
+      new String[0]);
+    if (isEmpty) {
+      boolean empty = false;
+      if (results != null) {
+        Iterator<String> it = results.iterator();
+        empty = !it.hasNext();
+      } else {
+        empty = true;
+      }
+      assert empty;
+      return;
+    } else {
+      assert results != null;
+    }
+
+    URL url = this.getClass().getResource(name + "-output.json");
+    File file = new File(url.toURI());
+    ArrayList<Element> expected =
+      convertIterator(Files.readLines(file,Charsets.UTF_8).iterator());
+    ArrayList<Element> result = convertIterator(results.iterator());
+    checkResult(expected, result);
+  }
+
+  private void testDbOutput(String name) throws Exception {
+    GiraphConfiguration conf = new GiraphConfiguration();
+    GIRAPH_REXSTER_HOSTNAME.set(conf, "127.0.0.1");
+    GIRAPH_REXSTER_PORT.set(conf, 18182);
+    GIRAPH_REXSTER_OUTPUT_GRAPH.set(conf, name);
+    conf.setComputationClass(EmptyComputation.class);
+    conf.setVertexInputFormatClass(
+      JsonLongDoubleFloatDoubleVertexInputFormat.class);
+    conf.setVertexOutputFormatClass(
+      RexsterLongDoubleFloatVertexOutputFormat.class);
+    conf.setEdgeOutputFormatClass(
+      RexsterLongDoubleFloatEdgeOutputFormat.class);
+
+    /* graph used for testing */
+    String[] graph = new String[] {
+      "[1,0,[[2,1],[4,3]]]",
+      "[2,0,[[1,1],[3,2],[4,1]]]",
+      "[3,0,[[2,2]]]",
+      "[4,0,[[1,3],[5,4],[2,1]]]",
+      "[5,0,[[3,4],[4,4]]]"
+    };
+
+    InternalVertexRunner.run(conf, graph);
+    URL url = this.getClass().getResource(name + "-output.json");
+    File file = new File(url.toURI());
+    ArrayList<Element> expected =
+      convertIterator(Files.readLines(file,Charsets.UTF_8).iterator());
+    ArrayList<Element> result = getRexsterContent(name);
+    checkResult(expected, result);
+  }
+
+  /**
+   * Test compute method that sends each edge a notification of its parents.
+   * The test set only has a 1-1 parent-to-child ratio for this unit test.
+   */
+  public static class EmptyComputation
+    extends BasicComputation<LongWritable, DoubleWritable,
+              FloatWritable, LongWritable> {
+    @Override
+    public void compute(
+      Vertex<LongWritable, DoubleWritable, FloatWritable> vertex,
+      Iterable<LongWritable> messages) throws IOException {
+
+      vertex.voteToHalt();
+    }
+  }
+
+  /**
+   * Start the Rexster server by preparing the configuration file loaded via
+   * the resources and setting other important parameters.
+   */
+  @SuppressWarnings("unchecked")
+  private static void startRexsterServer() throws Exception {
+    InputStream rexsterConf =
+      TestRexsterLongDoubleFloatIOFormat.class.getResourceAsStream(
+        REXSTER_CONF);
+    XMLConfiguration properties = new XMLConfiguration();
+    properties.load(rexsterConf);
+    rexsterConf.close();
+
+    List<HierarchicalConfiguration> graphConfigs =
+      properties.configurationsAt(Tokens.REXSTER_GRAPH_PATH);
+    RexsterApplication application  = new XmlRexsterApplication(graphConfigs);
+    server = new HttpRexsterServer(properties);
+
+    int scriptEngineThreshold =
+      properties.getInt("script-engine-reset-threshold",
+                        EngineController.RESET_NEVER);
+    String scriptEngineInitFile =
+      properties.getString("script-engine-init", "");
+
+    /* allow scriptengines to be configured so that folks can drop in
+       different gremlin flavors. */
+    List<String> scriptEngineNames = properties.getList("script-engines");
+
+    if (scriptEngineNames == null) {
+      /* configure to default with gremlin-groovy */
+      EngineController.configure(scriptEngineThreshold, scriptEngineInitFile);
+    } else {
+      EngineController.configure(scriptEngineThreshold, scriptEngineInitFile,
+                                 new HashSet<String>(scriptEngineNames));
+    }
+    server.start(application);
+  }
+
+  private static void stopRexsterServer() throws Exception {
+    try {
+      server.stop();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private static void deleteDbs() throws Exception {
+    for (int i = 0; i < DATABASES.length; ++i) {
+      FileUtils.deleteDirectory(new File(TMP_DIR + DATABASES[i]));
+      FileUtils.deleteDirectory(new File(TMP_DIR + "empty" + DATABASES[i]));
+    }
+    FileUtils.deleteDirectory(new File(TMP_DIR + EMPTYDB));
+  }
+
+  private static void insertDbData() throws Exception {
+    for (int i = 0; i < DATABASES.length; ++i) {
+      URL obj = new URL("http://127.0.0.1:18182/graphs/" + DATABASES[i] +
+        "/tp/giraph/vertices");
+      HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
+      conn.setRequestMethod("POST");
+      conn.setRequestProperty("Accept", "*/*");
+      conn.setRequestProperty("Content-Type",
+          "application/json; charset=UTF-8");
+      conn.setDoOutput(true);
+      DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
+      /* write the JSON to be sent */
+      wr.writeBytes("{ \"vlabel\":\"_vid\", \"tx\":[ ");
+      wr.writeBytes("{ \"value\":0,\"_vid\":0 },");
+      wr.writeBytes("{ \"value\":0,\"_vid\":1 },");
+      wr.writeBytes("{ \"value\":0,\"_vid\":2 },");
+      wr.writeBytes("{ \"value\":0,\"_vid\":3 },");
+      wr.writeBytes("{ \"value\":0,\"_vid\":4 }");
+      wr.writeBytes(" ] }");
+      int responseCode = conn.getResponseCode();
+      if (responseCode != 200) {
+        throw new RuntimeException("Unable to insert data in " + DATABASES[i] +
+          " code: " + responseCode );
+      }
+      BufferedReader in = new BufferedReader(
+          new InputStreamReader(conn.getInputStream()));
+      String inputLine;
+      StringBuffer response = new StringBuffer();
+      while ((inputLine = in.readLine()) != null) {
+        response.append(inputLine);
+      }
+      in.close();
+
+      obj = new URL("http://127.0.0.1:18182/graphs/" + DATABASES[i] +
+        "/tp/giraph/edges");
+      conn = (HttpURLConnection) obj.openConnection();
+      conn.setRequestMethod("POST");
+      conn.setRequestProperty("Accept", "*/*");
+      conn.setRequestProperty("Content-Type",
+          "application/json; charset=UTF-8");
+      conn.setDoOutput(true);
+      wr = new DataOutputStream(conn.getOutputStream());
+      /* write the JSON to be sent */
+      wr.writeBytes("{ \"vlabel\":\"_vid\", \"tx\":[ ");
+      wr.writeBytes("{ \"value\": 1, \"_outV\": 0, \"_inV\": 1 },");
+      wr.writeBytes("{ \"value\": 3, \"_outV\": 0, \"_inV\": 3 },");
+      wr.writeBytes("{ \"value\": 1, \"_outV\": 1, \"_inV\": 0 },");
+      wr.writeBytes("{ \"value\": 2, \"_outV\": 1, \"_inV\": 2 },");
+      wr.writeBytes("{ \"value\": 1, \"_outV\": 1, \"_inV\": 3 },");
+      wr.writeBytes("{ \"value\": 5, \"_outV\": 2, \"_inV\": 1 },");
+      wr.writeBytes("{ \"value\": 4, \"_outV\": 2, \"_inV\": 4 },");
+      wr.writeBytes("{ \"value\": 3, \"_outV\": 3, \"_inV\": 0 },");
+      wr.writeBytes("{ \"value\": 1, \"_outV\": 3, \"_inV\": 1 },");
+      wr.writeBytes("{ \"value\": 4, \"_outV\": 3, \"_inV\": 4 },");
+      wr.writeBytes("{ \"value\": 4, \"_outV\": 4, \"_inV\": 3 },");
+      wr.writeBytes("{ \"value\": 4, \"_outV\": 4, \"_inV\": 2 }");
+      wr.writeBytes(" ] }");
+      wr.flush();
+      wr.close();
+      responseCode = conn.getResponseCode();
+      if (responseCode != 200) {
+        throw new RuntimeException("Unable to insert data in " + DATABASES[i] +
+          " code: " + responseCode );
+      }
+      in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+      response = new StringBuffer();
+      while ((inputLine = in.readLine()) != null) {
+        response.append(inputLine);
+      }
+      in.close();
+    }
+  }
+
+  private ArrayList<Element> convertIterator(Iterator<String> elementit)
+    throws JSONException {
+    ArrayList<Element> result = new ArrayList<Element>();
+    while(elementit.hasNext()) {
+      JSONArray vertex = new JSONArray(elementit.next());
+      Element element = new Element(vertex.getLong(0), vertex.getLong(1));
+      JSONArray edges = vertex.getJSONArray(2);
+      for (int i = 0; i < edges.length(); ++i) {
+        element.add(edges.getJSONArray(i).toString());
+      }
+      result.add(element);
+    }
+    return result;
+  }
+
+  private ArrayList<Element> getRexsterContent(String name) throws Exception {
+    ArrayList<Element> result = new ArrayList<Element>();
+    /* get all the vertices */
+    URL url = new URL("http://127.0.0.1:18182/graphs/" + name +
+      "/tp/giraph/vertices");
+    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+    conn.setRequestMethod("GET");
+    conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+
+    InputStream is = conn.getInputStream();
+    StringBuffer json = new StringBuffer();
+    BufferedReader br = new BufferedReader(new InputStreamReader(is));
+    while (br.ready()) {
+      json.append(br.readLine());
+    }
+    br.close();
+    is.close();
+
+    JSONObject results = new JSONObject(json.toString());
+    JSONArray vertices = results.getJSONArray("results");
+    for (int i = 0; i < vertices.length(); ++i) {
+      JSONObject vertex = vertices.getJSONObject(i);
+      long id = getId(vertex, "_id");
+      result.add(new Element(id, 0));
+    }
+
+    /* get all the edges */
+    url = new URL("http://127.0.0.1:18182/graphs/" + name + "/tp/giraph/edges");
+    conn = (HttpURLConnection) url.openConnection();
+    conn.setRequestMethod("GET");
+    conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+
+    is = conn.getInputStream();
+    json = new StringBuffer();
+    br = new BufferedReader(new InputStreamReader(is));
+    while (br.ready()) {
+      json.append(br.readLine());
+    }
+    br.close();
+    is.close();
+
+    results = new JSONObject(json.toString());
+    JSONArray edges = results.getJSONArray("results");
+    for (int i = 0; i < edges.length(); ++i) {
+      JSONObject edge = edges.getJSONObject(i);
+      long inV = getId(edge, "_inV");
+      long outV = getId(edge, "_outV");
+      long value = edge.getLong("value");
+
+      for (int j = 0; j < result.size(); ++j) {
+        Element element = result.get(j);
+        if (element.id == outV) {
+          element.add("[" + inV + "," + value + "]");
+        }
+      }
+    }
+    return result;
+  }
+
+  private long getId(JSONObject obj, String label) throws Exception {
+    long id = 0;
+    try {
+      id = obj.getLong(label);
+    } catch(JSONException e) {
+      String idString = obj.getString(label);
+      String[] splits = idString.split(":");
+      id = Integer.parseInt(splits[1]);
+    }
+    return id;
+  }
+
+  protected void checkResult(ArrayList<Element> expected,
+    ArrayList<Element> result) throws Exception {
+    for (int i = 0; i < expected.size(); ++i) {
+      boolean found = false;
+      for (int j = 0; j < result.size(); ++j) {
+        if (expected.get(i).equals(result.get(j))) {
+          found = true;
+        }
+      }
+      assert found;
+    }
+  }
+
+  protected static class Element {
+    public long id;
+    public long value;
+    public ArrayList<String> edges;
+
+    public Element(long id, long value) {
+      this.id = id;
+      this.value = value;
+      this.edges = new ArrayList<String>();
+    }
+
+    public void add(String edge) {
+      edges.add(edge);
+    }
+
+    public boolean equals(Element obj) {
+      if (id != obj.id || value != obj.value) {
+        return false;
+      }
+      for (int i = 0; i < edges.size(); ++i) {
+        boolean found = false;
+        for (int j = 0; j < obj.edges.size(); ++j) {
+          if (edges.get(i).equals(obj.edges.get(j))) {
+            found = true;
+          }
+        }
+        if (found == false) {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    public String toString() {
+      StringBuffer sb = new StringBuffer();
+      sb.append("id: ");
+      sb.append(id);
+      sb.append(" value: ");
+      sb.append(value);
+      sb.append(" edges: ");
+      for (String element : edges) {
+        sb.append(element + " ");
+      }
+      return  sb.toString();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyneodb-output.json
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyneodb-output.json b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyneodb-output.json
new file mode 100644
index 0000000..fa9bbc7
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyneodb-output.json
@@ -0,0 +1,5 @@
+[1,0,[[4,4],[5,4]]]
+[2,0,[[3,1],[4,2],[5,1]]]
+[3,0,[[2,1],[5,3]]]
+[4,0,[[2,2]]]
+[5,0,[[3,3],[1,4],[2,1]]]

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyorientdb-output.json
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyorientdb-output.json b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyorientdb-output.json
new file mode 100644
index 0000000..3475404
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptyorientdb-output.json
@@ -0,0 +1,5 @@
+[0,0,[[3,4],[4,4]]]
+[1,0,[[2,1],[3,2],[4,1]]]
+[2,0,[[1,1],[4,3]]]
+[3,0,[[1,2]]]
+[4,0,[[2,3],[0,4],[1,1]]]

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptytgdb-output.json
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptytgdb-output.json b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptytgdb-output.json
new file mode 100644
index 0000000..ba2dd56
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/emptytgdb-output.json
@@ -0,0 +1,5 @@
+[0,0,[[3,4],[4,4]]]
+[1,0,[[4,1],[3,2],[2,1]]]
+[2,0,[[1,1],[4,3]]]
+[3,0,[[1,2]]]
+[4,0,[[2,3],[0,4],[1,1]]]

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/neodb-output.json
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/neodb-output.json b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/neodb-output.json
new file mode 100644
index 0000000..f318227
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/neodb-output.json
@@ -0,0 +1,5 @@
+[1,0,[[2,1],[4,3]]]
+[2,0,[[1,1],[3,5],[4,1]]]
+[3,0,[[2,2]]]
+[4,0,[[1,3],[2,1],[5,4]]]
+[5,0,[[3,4],[4,4]]]

http://git-wip-us.apache.org/repos/asf/giraph/blob/5d1bc2de/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/orientdb-output.json
----------------------------------------------------------------------
diff --git a/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/orientdb-output.json b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/orientdb-output.json
new file mode 100644
index 0000000..c12cc3e
--- /dev/null
+++ b/giraph-rexster/giraph-rexster-io/src/test/resources/org/apache/giraph/rexster/io/formats/orientdb-output.json
@@ -0,0 +1,5 @@
+[0,0,[[1,1],[3,3]]]
+[1,0,[[0,1],[2,5],[3,1]]]
+[2,0,[[1,2]]]
+[3,0,[[0,3],[1,1],[4,4]]]
+[4,0,[[3,4],[2,4]]]