Browse Source

Merge pull request #2060 from zapov/round-14

Simplify Revenj setup.
Nate 9 years ago
parent
commit
f1423cc115
29 changed files with 624 additions and 114 deletions
  1. 3 1
      frameworks/CSharp/revenj/README.md
  2. 4 2
      frameworks/CSharp/revenj/Revenj.Bench/Context.cs
  3. 18 0
      frameworks/CSharp/revenj/Revenj.Bench/FortuneTemplate.cs
  4. 391 0
      frameworks/CSharp/revenj/Revenj.Bench/Fortunes.cs
  5. 14 0
      frameworks/CSharp/revenj/Revenj.Bench/Fortunes.tt
  6. 29 9
      frameworks/CSharp/revenj/Revenj.Bench/RestService.cs
  7. 14 0
      frameworks/CSharp/revenj/Revenj.Bench/Revenj.Bench.csproj
  8. 5 1
      frameworks/CSharp/revenj/Revenj.Bench/model.dsl
  9. 2 0
      frameworks/CSharp/revenj/benchmark_config.json
  10. 1 1
      frameworks/CSharp/revenj/install.sh
  11. 6 17
      frameworks/CSharp/revenj/setup.ps1
  12. 7 14
      frameworks/CSharp/revenj/setup.sh
  13. 3 1
      frameworks/CSharp/revenj/source_code
  14. 5 2
      frameworks/Java/revenj/README.md
  15. 1 0
      frameworks/Java/revenj/benchmark_config.json
  16. 28 12
      frameworks/Java/revenj/pom.xml
  17. 1 38
      frameworks/Java/revenj/setup.sh
  18. 2 0
      frameworks/Java/revenj/source_code
  19. 12 8
      frameworks/Java/revenj/src/main/java/hello/Context.java
  20. 1 1
      frameworks/Java/revenj/src/main/java/hello/DbServlet.java
  21. 24 0
      frameworks/Java/revenj/src/main/java/hello/FortunesServlet.java
  22. 3 2
      frameworks/Java/revenj/src/main/java/hello/QueriesServlet.java
  23. 3 4
      frameworks/Java/revenj/src/main/java/hello/UpdatesServlet.java
  24. 1 1
      frameworks/Java/revenj/src/main/java/hello/Utils.java
  25. 4 0
      frameworks/Java/revenj/src/main/java/hello/model.dsl
  26. 15 0
      frameworks/Java/revenj/src/main/webapp/WEB-INF/jsp/fortunes.jsp
  27. 9 0
      frameworks/Java/revenj/src/main/webapp/WEB-INF/web.xml
  28. 9 0
      frameworks/Java/revenj/web.xml
  29. 9 0
      toolset/setup/linux/languages/dsl_platform.sh

+ 3 - 1
frameworks/CSharp/revenj/README.md

@@ -2,6 +2,7 @@
 
 Revenj HTTP server + DB API + JSON API + PostgreSQL.
 It uses precompiled DSL model for POCO classes.
+It uses T4 Templates for HTML output
 
 ## DSL model
 Data structures are defined in a DSL schema
@@ -19,6 +20,7 @@ Data structures are defined in a DSL schema
  * DB - `http://localhost:8080/bench/db`
  * Queries - `http://localhost:8080/bench/queries/{count}`
  * Updates -  `http://localhost:8080/bench/updates/{count}`
+ * Fortune -  `http://localhost:8080/bench/fortunes`
 
 ## Software Versions
 The tests were run with:
@@ -26,4 +28,4 @@ The tests were run with:
  * [Mono 4.2](http://www.mono-project.com/)
  * [.NET 4.0](https://www.microsoft.com/net)
  * [Postgres 9.3](http://www.postgresql.org/)
- * [Revenj.NET 1.2.1](http://github.com/ngs-doo/revenj)
+ * [Revenj.NET 1.3.1](http://github.com/ngs-doo/revenj)

+ 4 - 2
frameworks/CSharp/revenj/Revenj.Bench/Context.cs

@@ -13,7 +13,8 @@ namespace Revenj.Bench
 	{
 		public readonly ChunkedMemoryStream Stream;
 		public readonly TextWriter Writer;
-		public readonly IPersistableRepository<World> Repository;
+		public readonly IPersistableRepository<World> WorldRepository;
+		public readonly IQueryableRepository<Fortune> FortuneRepository;
 		public readonly IRepositoryBulkReader BulkReader;
 		public readonly Lazy<World>[] LazyWorlds = new Lazy<World>[512];
 		public readonly World[] Worlds = new World[512];
@@ -25,7 +26,8 @@ namespace Revenj.Bench
 			var dqm = service.Resolve<IDatabaseQueryManager>();
 			var factory = service.Resolve<IObjectFactory>().CreateInnerFactory();
 			factory.RegisterInterfaces(dqm.StartQuery(false));
-			Repository = factory.Resolve<IPersistableRepository<World>>();
+			WorldRepository = factory.Resolve<IPersistableRepository<World>>();
+			FortuneRepository = factory.Resolve<IQueryableRepository<Fortune>>();
 			BulkReader = factory.BulkRead(ChunkedMemoryStream.Static());
 		}
 	}

+ 18 - 0
frameworks/CSharp/revenj/Revenj.Bench/FortuneTemplate.cs

@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using System.IO;
+
+namespace Revenj.Bench
+{
+	public partial class Fortunes
+	{
+		private readonly TextWriter writer;
+
+		public Fortunes(List<KeyValuePair<int, string>> arg, TextWriter writer)
+		{
+			this._fortunesField = arg;
+			this.writer = writer;
+		}
+
+		public new void Write(string what) { writer.Write(what); }
+	}
+}

+ 391 - 0
frameworks/CSharp/revenj/Revenj.Bench/Fortunes.cs

@@ -0,0 +1,391 @@
+// ------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version: 10.0.0.0
+//  
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+// ------------------------------------------------------------------------------
+namespace Revenj.Bench
+{
+    using System;
+    
+    
+    #line 1 "C:\Projects\FrameworkBenchmarks\frameworks\CSharp\revenj\Revenj.Bench\Fortunes.tt"
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")]
+    public partial class Fortunes : FortunesBase
+    {
+        public virtual string TransformText()
+        {
+            this.Write("\n");
+            this.Write("\n");
+            this.Write("\n<!DOCTYPE html>\n<html>\n<head><title>Fortunes</title></head>\n<body><table><tr><th" +
+                    ">id</th><th>message</th></tr>\n");
+            
+            #line 1 "C:\Projects\FrameworkBenchmarks\frameworks\CSharp\revenj\Revenj.Bench\Fortunes.tt"
+ for (var i=0; i<fortunes.Count;i++) {
+	var f = fortunes[i]; 
+            
+            #line default
+            #line hidden
+            this.Write("\n<tr><td>");
+            
+            #line 1 "C:\Projects\FrameworkBenchmarks\frameworks\CSharp\revenj\Revenj.Bench\Fortunes.tt"
+ Write(f.Key.ToString()); 
+            
+            #line default
+            #line hidden
+            this.Write("</td><td>");
+            
+            #line 1 "C:\Projects\FrameworkBenchmarks\frameworks\CSharp\revenj\Revenj.Bench\Fortunes.tt"
+ Write(System.Web.HttpUtility.HtmlEncode(f.Value)); 
+            
+            #line default
+            #line hidden
+            this.Write("</td></tr>\n");
+            
+            #line 1 "C:\Projects\FrameworkBenchmarks\frameworks\CSharp\revenj\Revenj.Bench\Fortunes.tt"
+ } 
+            
+            #line default
+            #line hidden
+            this.Write("\n</table>\n</body>\n</html>");
+            return this.GenerationEnvironment.ToString();
+        }
+        
+        #line 1 "C:\Projects\FrameworkBenchmarks\frameworks\CSharp\revenj\Revenj.Bench\Fortunes.tt"
+
+private global::System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>> _fortunesField;
+
+/// <summary>
+/// Access the fortunes parameter of the template.
+/// </summary>
+private global::System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>> fortunes
+{
+    get
+    {
+        return this._fortunesField;
+    }
+}
+
+
+public virtual void Initialize()
+{
+    if ((this.Errors.HasErrors == false))
+    {
+bool fortunesValueAcquired = false;
+if (this.Session.ContainsKey("fortunes"))
+{
+    if ((typeof(global::System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>>).IsAssignableFrom(this.Session["fortunes"].GetType()) == false))
+    {
+        this.Error("The type \'System.Collections.Generic.List<System.Collections.Generic.KeyValuePair" +
+                "<int, string>>\' of the parameter \'fortunes\' did not match the type of the data p" +
+                "assed to the template.");
+    }
+    else
+    {
+        this._fortunesField = ((global::System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>>)(this.Session["fortunes"]));
+        fortunesValueAcquired = true;
+    }
+}
+if ((fortunesValueAcquired == false))
+{
+    object data = global::System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("fortunes");
+    if ((data != null))
+    {
+        if ((typeof(global::System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>>).IsAssignableFrom(data.GetType()) == false))
+        {
+            this.Error("The type \'System.Collections.Generic.List<System.Collections.Generic.KeyValuePair" +
+                    "<int, string>>\' of the parameter \'fortunes\' did not match the type of the data p" +
+                    "assed to the template.");
+        }
+        else
+        {
+            this._fortunesField = ((global::System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>>)(data));
+        }
+    }
+}
+
+
+    }
+}
+
+
+        
+        #line default
+        #line hidden
+    }
+    
+    #line default
+    #line hidden
+    #region Base class
+    /// <summary>
+    /// Base class for this transformation
+    /// </summary>
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")]
+    public class FortunesBase
+    {
+        #region Fields
+        private global::System.Text.StringBuilder generationEnvironmentField;
+        private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField;
+        private global::System.Collections.Generic.List<int> indentLengthsField;
+        private string currentIndentField = "";
+        private bool endsWithNewline;
+        private global::System.Collections.Generic.IDictionary<string, object> sessionField;
+        #endregion
+        #region Properties
+        /// <summary>
+        /// The string builder that generation-time code is using to assemble generated output
+        /// </summary>
+        protected System.Text.StringBuilder GenerationEnvironment
+        {
+            get
+            {
+                if ((this.generationEnvironmentField == null))
+                {
+                    this.generationEnvironmentField = new global::System.Text.StringBuilder();
+                }
+                return this.generationEnvironmentField;
+            }
+            set
+            {
+                this.generationEnvironmentField = value;
+            }
+        }
+        /// <summary>
+        /// The error collection for the generation process
+        /// </summary>
+        public System.CodeDom.Compiler.CompilerErrorCollection Errors
+        {
+            get
+            {
+                if ((this.errorsField == null))
+                {
+                    this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection();
+                }
+                return this.errorsField;
+            }
+        }
+        /// <summary>
+        /// A list of the lengths of each indent that was added with PushIndent
+        /// </summary>
+        private System.Collections.Generic.List<int> indentLengths
+        {
+            get
+            {
+                if ((this.indentLengthsField == null))
+                {
+                    this.indentLengthsField = new global::System.Collections.Generic.List<int>();
+                }
+                return this.indentLengthsField;
+            }
+        }
+        /// <summary>
+        /// Gets the current indent we use when adding lines to the output
+        /// </summary>
+        public string CurrentIndent
+        {
+            get
+            {
+                return this.currentIndentField;
+            }
+        }
+        /// <summary>
+        /// Current transformation session
+        /// </summary>
+        public virtual global::System.Collections.Generic.IDictionary<string, object> Session
+        {
+            get
+            {
+                return this.sessionField;
+            }
+            set
+            {
+                this.sessionField = value;
+            }
+        }
+        #endregion
+        #region Transform-time helpers
+        /// <summary>
+        /// Write text directly into the generated output
+        /// </summary>
+        public void Write(string textToAppend)
+        {
+            if (string.IsNullOrEmpty(textToAppend))
+            {
+                return;
+            }
+            // If we're starting off, or if the previous text ended with a newline,
+            // we have to append the current indent first.
+            if (((this.GenerationEnvironment.Length == 0) 
+                        || this.endsWithNewline))
+            {
+                this.GenerationEnvironment.Append(this.currentIndentField);
+                this.endsWithNewline = false;
+            }
+            // Check if the current text ends with a newline
+            if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture))
+            {
+                this.endsWithNewline = true;
+            }
+            // This is an optimization. If the current indent is "", then we don't have to do any
+            // of the more complex stuff further down.
+            if ((this.currentIndentField.Length == 0))
+            {
+                this.GenerationEnvironment.Append(textToAppend);
+                return;
+            }
+            // Everywhere there is a newline in the text, add an indent after it
+            textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField));
+            // If the text ends with a newline, then we should strip off the indent added at the very end
+            // because the appropriate indent will be added when the next time Write() is called
+            if (this.endsWithNewline)
+            {
+                this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length));
+            }
+            else
+            {
+                this.GenerationEnvironment.Append(textToAppend);
+            }
+        }
+        /// <summary>
+        /// Write text directly into the generated output
+        /// </summary>
+        public void WriteLine(string textToAppend)
+        {
+            this.Write(textToAppend);
+            this.GenerationEnvironment.AppendLine();
+            this.endsWithNewline = true;
+        }
+        /// <summary>
+        /// Write formatted text directly into the generated output
+        /// </summary>
+        public void Write(string format, params object[] args)
+        {
+            this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
+        }
+        /// <summary>
+        /// Write formatted text directly into the generated output
+        /// </summary>
+        public void WriteLine(string format, params object[] args)
+        {
+            this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
+        }
+        /// <summary>
+        /// Raise an error
+        /// </summary>
+        public void Error(string message)
+        {
+            System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
+            error.ErrorText = message;
+            this.Errors.Add(error);
+        }
+        /// <summary>
+        /// Raise a warning
+        /// </summary>
+        public void Warning(string message)
+        {
+            System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
+            error.ErrorText = message;
+            error.IsWarning = true;
+            this.Errors.Add(error);
+        }
+        /// <summary>
+        /// Increase the indent
+        /// </summary>
+        public void PushIndent(string indent)
+        {
+            if ((indent == null))
+            {
+                throw new global::System.ArgumentNullException("indent");
+            }
+            this.currentIndentField = (this.currentIndentField + indent);
+            this.indentLengths.Add(indent.Length);
+        }
+        /// <summary>
+        /// Remove the last indent that was added with PushIndent
+        /// </summary>
+        public string PopIndent()
+        {
+            string returnValue = "";
+            if ((this.indentLengths.Count > 0))
+            {
+                int indentLength = this.indentLengths[(this.indentLengths.Count - 1)];
+                this.indentLengths.RemoveAt((this.indentLengths.Count - 1));
+                if ((indentLength > 0))
+                {
+                    returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength));
+                    this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength));
+                }
+            }
+            return returnValue;
+        }
+        /// <summary>
+        /// Remove any indentation
+        /// </summary>
+        public void ClearIndent()
+        {
+            this.indentLengths.Clear();
+            this.currentIndentField = "";
+        }
+        #endregion
+        #region ToString Helpers
+        /// <summary>
+        /// Utility class to produce culture-oriented representation of an object as a string.
+        /// </summary>
+        public class ToStringInstanceHelper
+        {
+            private System.IFormatProvider formatProviderField  = global::System.Globalization.CultureInfo.InvariantCulture;
+            /// <summary>
+            /// Gets or sets format provider to be used by ToStringWithCulture method.
+            /// </summary>
+            public System.IFormatProvider FormatProvider
+            {
+                get
+                {
+                    return this.formatProviderField ;
+                }
+                set
+                {
+                    if ((value != null))
+                    {
+                        this.formatProviderField  = value;
+                    }
+                }
+            }
+            /// <summary>
+            /// This is called from the compile/run appdomain to convert objects within an expression block to a string
+            /// </summary>
+            public string ToStringWithCulture(object objectToConvert)
+            {
+                if ((objectToConvert == null))
+                {
+                    throw new global::System.ArgumentNullException("objectToConvert");
+                }
+                System.Type t = objectToConvert.GetType();
+                System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] {
+                            typeof(System.IFormatProvider)});
+                if ((method == null))
+                {
+                    return objectToConvert.ToString();
+                }
+                else
+                {
+                    return ((string)(method.Invoke(objectToConvert, new object[] {
+                                this.formatProviderField })));
+                }
+            }
+        }
+        private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper();
+        public ToStringInstanceHelper ToStringHelper
+        {
+            get
+            {
+                return this.toStringHelperField;
+            }
+        }
+        #endregion
+    }
+    #endregion
+}

+ 14 - 0
frameworks/CSharp/revenj/Revenj.Bench/Fortunes.tt

@@ -0,0 +1,14 @@
+<#@ template language="C#" #>
+<#@ assembly name="System.Web" #>
+<#@ parameter type="System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>>" name="fortunes" #>
+<!DOCTYPE html>
+<html>
+<head><title>Fortunes</title></head>
+<body><table><tr><th>id</th><th>message</th></tr>
+<# for (var i=0; i<fortunes.Count;i++) {
+	var f = fortunes[i]; #>
+<tr><td><# Write(f.Key.ToString()); #></td><td><# Write(System.Web.HttpUtility.HtmlEncode(f.Value)); #></td></tr>
+<# } #>
+</table>
+</body>
+</html>

+ 29 - 9
frameworks/CSharp/revenj/Revenj.Bench/RestService.cs

@@ -1,5 +1,5 @@
 using System;
-using System.ComponentModel;
+using System.Collections.Generic;
 using System.IO;
 using System.ServiceModel;
 using System.ServiceModel.Web;
@@ -17,28 +17,27 @@ namespace Revenj.Bench
 	{
 		[OperationContract]
 		[WebGet(UriTemplate = "/plaintext")]
-		[Description("Plain text response")]
 		Stream PlainText();
 
 		[OperationContract]
 		[WebGet(UriTemplate = "/json")]
-		[Description("JSON response")]
 		Stream JSON();
 
 		[OperationContract]
 		[WebGet(UriTemplate = "/db")]
-		[Description("Single database query")]
 		Stream SingleQuery();
 
 		[OperationContract]
 		[WebGet(UriTemplate = "/queries/{count}")]
-		[Description("Multiple database queries")]
 		Stream MultipleQueries(string count);
 
 		[OperationContract]
 		[WebGet(UriTemplate = "/updates/{count}")]
-		[Description("Database updates")]
 		Stream Updates(string count);
+
+		[OperationContract]
+		[WebGet(UriTemplate = "/fortunes")]
+		Stream Fortunes();
 	}
 
 	public class RestService : IRestService
@@ -95,7 +94,7 @@ namespace Revenj.Bench
 		{
 			var id = Random.Next(10000) + 1;
 			var ctx = GetContext(Services);
-			var world = ctx.Repository.Find(IDs[id]);
+			var world = ctx.WorldRepository.Find(IDs[id]);
 			return ReturnJSON(world, ctx.Stream);
 		}
 
@@ -144,11 +143,32 @@ namespace Revenj.Bench
 			for (int i = 0; i < result.Length; i++)
 				result[i].randomNumber = Random.Next(10000) + 1;
 			Array.Sort(result, ASC);
-			ctx.Repository.Update(result);
+			ctx.WorldRepository.Update(result);
 			var cms = ctx.Stream;
 			result.Serialize(cms);
 			ThreadContext.Response.ContentType = "application/json";
 			return cms;
 		}
+
+		private static readonly Comparison<KeyValuePair<int, string>> Comparison = (l, r) => string.Compare(l.Value, r.Value, StringComparison.Ordinal);
+
+		public Stream Fortunes()
+		{
+			var ctx = GetContext(Services);
+			var fortunes = ctx.FortuneRepository.Search();
+			var list = new List<KeyValuePair<int, string>>(fortunes.Length + 1);
+			foreach (var f in fortunes)
+				list.Add(new KeyValuePair<int, string>(f.id, f.message));
+			list.Add(new KeyValuePair<int, string>(0, "Additional fortune added at request time."));
+			list.Sort(Comparison);
+			var cms = ctx.Stream;
+			var writer = cms.GetWriter();
+			var template = new Fortunes(list, writer);
+			template.TransformText();
+			writer.Flush();
+			cms.Position = 0;
+			ThreadContext.Response.ContentType = "text/html; charset=UTF-8";
+			return cms;
+	}
 	}
-}
+}

+ 14 - 0
frameworks/CSharp/revenj/Revenj.Bench/Revenj.Bench.csproj

@@ -75,9 +75,16 @@
     <Reference Include="System.Core" />
     <Reference Include="System.ServiceModel" />
     <Reference Include="System.ServiceModel.Web" />
+    <Reference Include="System.Web" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Context.cs" />
+    <Compile Include="Fortunes.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Fortunes.tt</DependentUpon>
+    </Compile>
+    <Compile Include="FortuneTemplate.cs" />
     <Compile Include="RestService.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -85,11 +92,18 @@
       <Link>Revenj.Http.exe.config</Link>
       <SubType>Designer</SubType>
     </None>
+    <None Include="Fortunes.tt">
+      <Generator>TextTemplatingFilePreprocessor</Generator>
+      <LastGenOutput>Fortunes.cs</LastGenOutput>
+    </None>
     <None Include="model.dsl" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Properties\" />
   </ItemGroup>
+  <ItemGroup>
+    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 5 - 1
frameworks/CSharp/revenj/Revenj.Bench/model.dsl

@@ -6,4 +6,8 @@
 		int id;
 		int randomNumber from randomnumber;
 	}
-}
+	sql Fortune from fortune {
+	    int id;
+	    String message;
+	}
+}

+ 2 - 0
frameworks/CSharp/revenj/benchmark_config.json

@@ -8,6 +8,7 @@
       "query_url": "/bench/queries/",
       "plaintext_url": "/bench/plaintext",
       "update_url": "/bench/updates/",
+      "fortune_url": "/bench/fortunes",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",
@@ -30,6 +31,7 @@
       "query_url": "/bench/queries/",
       "plaintext_url": "/bench/plaintext",
       "update_url": "/bench/updates/",
+      "fortune_url": "/bench/fortunes",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",

+ 1 - 1
frameworks/CSharp/revenj/install.sh

@@ -1,3 +1,3 @@
 #!/bin/bash
 
-fw_depends mono java
+fw_depends mono java dsl_platform

+ 6 - 17
frameworks/CSharp/revenj/setup.ps1

@@ -3,6 +3,9 @@ param($action)
 if (!$TROOT) {
   $TROOT = "C:\FrameworkBenchmarks\frameworks\CSharp\revenj"
 }
+if (!$IROOT) {
+  $IROOT = "C:\FrameworkBenchmarks\installs"
+}
 if (!$DBHOST) {
   $DBHOST = "localhost"
 }
@@ -13,7 +16,6 @@ $msbuild = $Env:windir + "\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
 $java=$Env:JAVA_HOME + "\bin\java"
 $dslclc=$TROOT + "\dsl-clc.jar"
 $httpZip=$TROOT + "\http-server.zip"
-$dslZip=$TROOT + "\dsl-compiler.zip"
 $sln=$TROOT + "\Revenj.Bench.sln"
 $revenj=$TROOT + "\exe\Revenj.Http.exe"
 $exe=$TROOT + "\exe\"
@@ -34,33 +36,20 @@ if ($action -eq 'start') {
 	if (Test-Path $TROOT/http-server.zip) {
 	  rm $TROOT/http-server.zip
 	}
-	if (Test-Path $TROOT/dsl-compiler.zip) {
-	  rm $TROOT/dsl-compiler.zip
-	}
-	if (Test-Path $TROOT/dsl-compiler.exe) {
-	  rm $TROOT/dsl-compiler.exe
-	}
 
 	echo "Download DSL compiler client"
 	$client = new-object System.Net.WebClient
-	$client.DownloadFile( "https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.5.0/dsl-clc.jar", $dslclc )
+	$client.DownloadFile( "https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.7.0/dsl-clc.jar", $dslclc )
 
 	echo "Download Revenj HTTP server"
 	$client = new-object System.Net.WebClient
-	$client.DownloadFile( "https://github.com/ngs-doo/revenj/releases/download/1.2.1/http-server.zip", $httpZip )
+	$client.DownloadFile( "https://github.com/ngs-doo/revenj/releases/download/1.3.1/http-server.zip", $httpZip )
 
 	echo "Unzipping HTTP server"
 	[System.IO.Compression.ZipFile]::ExtractToDirectory($httpZip, $exe)
 
-	echo "Download DSL compiler for Revenj.NET 1.2.1"
-	$client = new-object System.Net.WebClient
-	$client.DownloadFile( "https://github.com/ngs-doo/revenj/releases/download/1.2.1/dsl-compiler.zip", $dslZip )
-
-	echo "Unzipping DSL compiler"
-	[System.IO.Compression.ZipFile]::ExtractToDirectory($dslZip, $TROOT)
-	
 	echo "Compiling the server model and downloading DSL Platform compiler..."
-	&$java -jar $dslclc temp=$TROOT/tmp/ force dsl=$TROOT/Revenj.Bench manual-json revenj.net=$TROOT/exe/ServerModel.dll no-prompt dependencies:revenj.net=$TROOT/exe download compiler=$TROOT/dsl-compiler.exe
+	&$java -jar $dslclc temp=$TROOT/tmp/ force dsl=$TROOT/Revenj.Bench manual-json revenj.net=$TROOT/exe/ServerModel.dll no-prompt dependencies:revenj.net=$TROOT/exe compiler=$IROOT/dsl-compiler.exe
 
 	echo "Compiling the benchmark project..."
 	&$msbuild $sln /p:Configuration=Release /t:Rebuild

+ 7 - 14
frameworks/CSharp/revenj/setup.sh

@@ -1,36 +1,29 @@
 #!/bin/bash
 
-fw_depends java mono
+fw_depends java mono dsl_platform
 
 echo "Cleaning up..."
-rm -rf $TROOT/exe $TROOT/tmp $TROOT/dsl-clc.jar $TROOT/http-server.zip  $TROOT/dsl-compiler.zip $TROOT/dsl-compiler.exe
+rm -rf $TROOT/exe $TROOT/tmp $TROOT/dsl-clc.jar $TROOT/http-server.zip
 
 echo "Download DSL compiler client"
-wget -O $TROOT/dsl-clc.jar https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.5.0/dsl-clc.jar
+wget -O $TROOT/dsl-clc.jar https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.7.0/dsl-clc.jar
 
-echo "Download Revenj.NET HTTP server 1.2.1"
-wget -O $TROOT/http-server.zip https://github.com/ngs-doo/revenj/releases/download/1.2.1/http-server.zip
+echo "Download Revenj.NET HTTP server 1.3.1"
+wget -O $TROOT/http-server.zip https://github.com/ngs-doo/revenj/releases/download/1.3.1/http-server.zip
 
 echo "Unzipping HTTP server"
 unzip $TROOT/http-server.zip -d $TROOT/exe
 
-echo "Download DSL compiler for Revenj.NET 1.2.1"
-wget -O $TROOT/dsl-compiler.zip https://github.com/ngs-doo/revenj/releases/download/1.2.1/dsl-compiler.zip
-
-echo "Unzipping DSL compiler"
-unzip $TROOT/dsl-compiler.zip -d $TROOT
-
 echo "Compiling the server model and downloading dependencies..."
 java -jar $TROOT/dsl-clc.jar \
 	temp=$TROOT/tmp/ \
 	force \
 	dsl=$TROOT/Revenj.Bench \
 	manual-json \
-	compiler=$TROOT/dsl-compiler.exe \
+	compiler=$IROOT/dsl-compiler.exe \
 	revenj.net=$TROOT/exe/ServerModel.dll \
 	no-prompt \
-	dependencies:revenj.net=$TROOT/exe \
-	download
+	dependencies:revenj.net=$TROOT/exe
 
 echo "Compiling the benchmark project..."
 xbuild $TROOT/Revenj.Bench/Revenj.Bench.csproj /t:Rebuild /p:Configuration=Release

+ 3 - 1
frameworks/CSharp/revenj/source_code

@@ -1,4 +1,6 @@
 ./revenj/Revenj.Bench/Context.cs
-./revenj/Revenj.Bench/RestService.cs
+./revenj/Revenj.Bench/Fortunes.tt
+./revenj/Revenj.Bench/FortuneTemplate.cs
 ./revenj/Revenj.Bench/model.dsl
+./revenj/Revenj.Bench/RestService.cs
 ./revenj/Revenj.Http.exe.config

+ 5 - 2
frameworks/Java/revenj/README.md

@@ -2,6 +2,7 @@
 
 Servlet + Revenj DB API + DSL-JSON + PostgreSQL.
 It uses precompiled DSL model for POJO classes.
+It uses JSP for HTML output
 
 ### DSL model
 Data structures are defined in a DSL schema
@@ -15,6 +16,7 @@ Data structures are defined in a DSL schema
  * [DB](src/main/java/hello/DbServlet.java)
  * [Queries](src/main/java/hello/QueriesServlet.java)
  * [Updates](src/main/java/hello/UpdatesServlet.java)
+ * [Fortune](src/main/java/hello/FortunesServlet.java)
 
 ## Software Versions
 The tests were run with:
@@ -22,8 +24,8 @@ The tests were run with:
  * [Oracle Java 1.8](https://www.oracle.com/java/)
  * [Postgres 9.3](http://www.postgresql.org/)
  * [Resin 4.0](http://www.caucho.com/)
- * [DSL JSON 0.9.3](http://github.com/ngs-doo/dsl-json)
- * [Revenj.Java 0.8.0](http://github.com/ngs-doo/revenj)
+ * [DSL JSON 1.0.0](http://github.com/ngs-doo/dsl-json)
+ * [Revenj.Java 0.9.7](http://github.com/ngs-doo/revenj)
 
 ## Test URLs
 
@@ -32,3 +34,4 @@ The tests were run with:
  * DB - `http://localhost:8080/revenj/db`
  * Queries - `http://localhost:8080/revenj/queries?queries={count}`
  * Updates -  `http://localhost:8080/revenj/updates?queries={count}`
+ * Fortune -  `http://localhost:8080/revenj/fortunes`

+ 1 - 0
frameworks/Java/revenj/benchmark_config.json

@@ -8,6 +8,7 @@
       "db_url": "/revenj/db",
       "query_url": "/revenj/queries?queries=",
       "update_url": "/revenj/updates?queries=",
+      "fortune_url": "/revenj/fortunes",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",

+ 28 - 12
frameworks/Java/revenj/pom.xml

@@ -10,23 +10,17 @@
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 	</properties>
-	<repositories>
-		<repository>
-			<id>model</id>
-			<url>file:${project.basedir}/model</url>
-		</repository>
-	</repositories>
 	<dependencies>
-		<dependency>
-			<groupId>dsl</groupId>
-			<artifactId>gen-model</artifactId>
-			<version>1.0</version>
-		</dependency>
 		<dependency>
 			<groupId>org.revenj</groupId>
 			<artifactId>revenj-core</artifactId>
-			<version>0.8.0</version>
+			<version>0.9.7</version>
 		</dependency>
+                <dependency>
+                        <groupId>org.apache.commons</groupId>
+                        <artifactId>commons-lang3</artifactId>
+                        <version>3.4</version>
+                </dependency>
 		<dependency>
 			<groupId>javax.servlet</groupId>
 			<artifactId>servlet-api</artifactId>
@@ -36,6 +30,28 @@
 	</dependencies>
 	<build>
 		<plugins>
+			<plugin>
+				<groupId>com.dslplatform</groupId>
+				<artifactId>dsl-platform-maven-plugin</artifactId>
+				<version>0.8</version>
+				<executions>
+					<execution>
+						<phase>generate-sources</phase>
+						<goals>
+							<goal>generate-code</goal>
+						</goals>
+						<configuration>
+							<target>revenj.java</target>
+							<dsl>${project.build.sourceDirectory}</dsl>
+							<namespace>dsl</namespace>
+							<compiler>${project.basedir}/../../../installs/dsl-compiler.exe</compiler>
+							<options>
+								<option>manual-json</option>
+							</options>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>

+ 1 - 38
frameworks/Java/revenj/setup.sh

@@ -1,46 +1,9 @@
 #!/bin/bash
 
-fw_depends java resin maven mono
+fw_depends java resin maven mono dsl_platform
 
 source $IROOT/java.installed
 
-echo "Cleaning up..."
-rm -rf $TROOT/tmp $TROOT/model $TROOT/revenj.java $TROOT/dsl-clc.jar $TROOT/dsl-compiler.zip $TROOT/dsl-compiler.exe $TROOT/revenj-java-0.8.zip
-
-echo "Download DSL compiler client"
-wget -O $TROOT/dsl-clc.jar https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.5.0/dsl-clc.jar
-
-echo "Download compatible DSL compiler"
-wget -O $TROOT/dsl-compiler.zip https://github.com/ngs-doo/revenj/releases/download/1.2.1/dsl-compiler.zip
-
-echo "Unzipping DSL compiler"
-unzip $TROOT/dsl-compiler.zip -d $TROOT
-
-echo "Prepare Revenj 0.8 dependencies"
-wget -O $TROOT/revenj-java-0.8.zip https://github.com/ngs-doo/revenj/releases/download/1.2.1/revenj-java-0.8.zip
-unzip $TROOT/revenj-java-0.8.zip -d $TROOT/revenj.java
-
-echo "Compiling the server model and downloading dependencies..."
-java -jar $TROOT/dsl-clc.jar \
-	temp=$TROOT/tmp/ \
-	force \
-	dsl=$TROOT/src \
-	manual-json \
-	compiler=$TROOT/dsl-compiler.exe \
-	namespace=dsl \
-	revenj.java=$TROOT/model/gen-model.jar \
-	no-prompt \
-	download
-
-echo "Adding model to local Maven repository..."
-mvn deploy:deploy-file \
-	-Durl=file://model \
-	-Dfile=model/gen-model.jar \
-	-DgroupId=dsl \
-	-DartifactId=gen-model \
-	-Dpackaging=jar \
-	-Dversion=1.0
-
 echo "Changing the database"
 cat $TROOT/web.xml | sed 's/localhost/'$DBHOST'/g' > $TROOT/src/main/webapp/WEB-INF/web.xml
 	

+ 2 - 0
frameworks/Java/revenj/source_code

@@ -1,9 +1,11 @@
 ./revenj/src/main/java/hello/Context.java
 ./revenj/src/main/java/hello/DbServlet.java
 ./revenj/src/main/java/hello/JsonServlet.java
+./revenj/src/main/java/hello/FortunesServlet.java
 ./revenj/src/main/java/hello/model.dsl
 ./revenj/src/main/java/hello/PlaintextServlet.java
 ./revenj/src/main/java/hello/QueriesServlet.java
 ./revenj/src/main/java/hello/UpdatesServlet.java
 ./revenj/src/main/java/hello/Utils.java
+./revenj/src/main/webapp/WEB-INF/jsp/fortunes.jsp
 ./revenj/src/main/webapp/WEB-INF/web.xml

+ 12 - 8
frameworks/Java/revenj/src/main/java/hello/Context.java

@@ -2,8 +2,8 @@ package hello;
 
 import com.dslplatform.json.JsonWriter;
 import dsl.Boot;
-import dsl.FrameworkBench.World;
-import dsl.FrameworkBench.repositories.WorldRepository;
+import dsl.FrameworkBench.*;
+import dsl.FrameworkBench.repositories.*;
 import org.revenj.extensibility.Container;
 import org.revenj.patterns.*;
 
@@ -29,12 +29,13 @@ class Context {
 	}
 
 	public final JsonWriter json;
-	public final WorldRepository repository;
+	public final WorldRepository worlds;
+	public final FortuneRepository fortunes;
 	public final Connection connection;
 	private final ThreadLocalRandom random;
 	public final RepositoryBulkReader bulkReader;
-	public final World[] worlds = new World[512];
-	public final Callable[] callables = new Callable[512];
+	private final World[] buffer = new World[512];
+	private final Callable[] callables = new Callable[512];
 
 	public Context() {
 		try {
@@ -44,7 +45,8 @@ class Context {
 			ctx.registerInstance(connection);
 			this.json = new JsonWriter();
 			this.random = ThreadLocalRandom.current();
-			this.repository = ctx.resolve(WorldRepository.class);
+			this.worlds = ctx.resolve(WorldRepository.class);
+			this.fortunes = ctx.resolve(FortuneRepository.class);
 			this.bulkReader = ctx.resolve(RepositoryBulkReader.class);
 		} catch (Exception e) {
 			throw new RuntimeException(e);
@@ -55,7 +57,8 @@ class Context {
 		return random.nextInt(10000) + 1;
 	}
 
-	public void loadWorlds(final int count) throws IOException {
+	@SuppressWarnings("unchecked")
+	public World[] loadWorlds(final int count) throws IOException {
 		bulkReader.reset();
 		for (int i = 0; i < count; i++) {
 			callables[i] = bulkReader.find(World.class, Integer.toString(getRandom10k()));
@@ -63,10 +66,11 @@ class Context {
 		bulkReader.execute();
 		try {
 			for (int i = 0; i < count; i++) {
-				worlds[i] = ((Optional<World>) callables[i].call()).get();
+				buffer[i] = ((Optional<World>) callables[i].call()).get();
 			}
 		} catch (Exception e) {
 			throw new IOException(e);
 		}
+		return buffer;
 	}
 }

+ 1 - 1
frameworks/Java/revenj/src/main/java/hello/DbServlet.java

@@ -15,7 +15,7 @@ public class DbServlet extends HttpServlet {
 	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
 		res.setContentType("application/json");
 		final Context ctx = Utils.getContext();
-		final Optional<World> world = ctx.repository.find(ctx.getRandom10k(), ctx.connection);
+		final Optional<World> world = ctx.worlds.find(ctx.getRandom10k(), ctx.connection);
 		final JsonWriter writer = ctx.json;
 		world.get().serialize(writer, false);
 		writer.toStream(res.getOutputStream());

+ 24 - 0
frameworks/Java/revenj/src/main/java/hello/FortunesServlet.java

@@ -0,0 +1,24 @@
+package hello;
+
+import dsl.FrameworkBench.Fortune;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.*;
+import java.io.IOException;
+import java.util.*;
+
+public class FortunesServlet extends HttpServlet {
+
+	private static final Comparator<Fortune> COMPARATOR = (o1, o2) -> o1.getMessage().compareTo(o2.getMessage());
+
+	@Override
+	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
+		final Context ctx = Utils.getContext();
+		final List<Fortune> fortunes = ctx.fortunes.search();
+		fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+		Collections.sort(fortunes, COMPARATOR);
+		req.setCharacterEncoding("UTF-8");
+		req.setAttribute("fortunes", fortunes);
+		req.getRequestDispatcher("/WEB-INF/jsp/fortunes.jsp").forward(req, res);
+	}
+}

+ 3 - 2
frameworks/Java/revenj/src/main/java/hello/QueriesServlet.java

@@ -1,6 +1,7 @@
 package hello;
 
 import com.dslplatform.json.JsonWriter;
+import dsl.FrameworkBench.World;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.*;
@@ -14,8 +15,8 @@ public class QueriesServlet extends HttpServlet {
 		final int count = Utils.parseBoundParam(req);
 		final Context ctx = Utils.getContext();
 		final JsonWriter json = ctx.json;
-		ctx.loadWorlds(count);
-		json.serialize(ctx.worlds, count);
+		final World[] worlds = ctx.loadWorlds(count);
+		json.serialize(worlds, count);
 		json.toStream(res.getOutputStream());
 	}
 }

+ 3 - 4
frameworks/Java/revenj/src/main/java/hello/UpdatesServlet.java

@@ -18,15 +18,14 @@ public class UpdatesServlet extends HttpServlet {
 		final int count = Utils.parseBoundParam(req);
 		final Context ctx = Utils.getContext();
 		final JsonWriter json = ctx.json;
-		ctx.loadWorlds(count);
-		final World[] worlds = ctx.worlds;
+		final World[] worlds = ctx.loadWorlds(count);
 		final ArrayList<World> changed = new ArrayList<>(count);
 		for (int i = 0; i < count; i++) {
 			changed.add(worlds[i].setRandomNumber(ctx.getRandom10k()));
 		}
 		Collections.sort(changed, ASC);
-		ctx.repository.update(changed);
+		ctx.worlds.update(changed);
 		json.serialize(worlds, count);
 		json.toStream(res.getOutputStream());
 	}
-}
+}

+ 1 - 1
frameworks/Java/revenj/src/main/java/hello/Utils.java

@@ -3,7 +3,7 @@ package hello;
 import javax.servlet.http.HttpServletRequest;
 import java.io.IOException;
 
-class Utils {
+abstract class Utils {
 
 	private static final ThreadLocal<Context> threadContext = new ThreadLocal<Context>() {
 		@Override

+ 4 - 0
frameworks/Java/revenj/src/main/java/hello/model.dsl

@@ -6,4 +6,8 @@ module FrameworkBench {
 		int id;
 		int randomNumber from randomnumber;
 	}
+	sql Fortune from fortune {
+	    int id;
+	    String message;
+	}
 } 

+ 15 - 0
frameworks/Java/revenj/src/main/webapp/WEB-INF/jsp/fortunes.jsp

@@ -0,0 +1,15 @@
+<%@ page import="dsl.FrameworkBench.*,java.util.*,org.apache.commons.lang3.*" session="false" %>
+<% List<Fortune> fortunes = (List)request.getAttribute("fortunes"); %>
+<!DOCTYPE html>
+<html>
+<head><title>Fortunes</title></head>
+<body>
+<table>
+<tr><th>id</th><th>message</th></tr>
+<%  for (int i=0; i<fortunes.size(); i++) {
+    Fortune f = fortunes.get(i); %>
+<tr><td><%= f.getId() %></td><td><%= StringEscapeUtils.escapeHtml4(f.getMessage()) %></td></tr>
+<%  } %>
+</table>
+</body>
+</html>

+ 9 - 0
frameworks/Java/revenj/src/main/webapp/WEB-INF/web.xml

@@ -49,4 +49,13 @@
         <servlet-name>updates</servlet-name>
         <url-pattern>/updates</url-pattern>
     </servlet-mapping>
+    <servlet>
+        <servlet-name>fortunes</servlet-name>
+        <servlet-class>hello.FortunesServlet</servlet-class>
+        <load-on-startup>2</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>fortunes</servlet-name>
+        <url-pattern>/fortunes</url-pattern>
+    </servlet-mapping>
 </web-app>

+ 9 - 0
frameworks/Java/revenj/web.xml

@@ -49,4 +49,13 @@
         <servlet-name>updates</servlet-name>
         <url-pattern>/updates</url-pattern>
     </servlet-mapping>
+    <servlet>
+        <servlet-name>fortunes</servlet-name>
+        <servlet-class>hello.FortunesServlet</servlet-class>
+        <load-on-startup>2</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>fortunes</servlet-name>
+        <url-pattern>/fortunes</url-pattern>
+    </servlet-mapping>
 </web-app>

+ 9 - 0
toolset/setup/linux/languages/dsl_platform.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+RETCODE=$(fw_exists $IROOT/dsl-compiler.exe)
+[ ! "$RETCODE" == 0 ] || { \
+  return 0; }
+
+wget -O $IROOT/dsl-compiler.zip https://github.com/ngs-doo/revenj/releases/download/1.3.1/dsl-compiler.zip
+unzip $IROOT/dsl-compiler.zip -d $IROOT
+rm $IROOT/dsl-compiler.zip