Repository: incubator-reef Updated Branches: refs/heads/master 76d101014 -> 64f7e0a03
[REEF-193] serialize http header info with HttpRequest This PR is to add http header data cross the bridge * Update http request schema to add header entry * Update AvroHttpSerializer at java side for the change * Updated ParsedHttpRequest to return the header info * Update test java cases * Updated AvroHttpSerializer as C# side * Added test project for Common.Tests * Added unit tests cases for http serializer in C# JIRA: Reef-193. (https://issues.apache.org/jira/browse/REEF-193) Author: Julia Wang Email: [email protected] Project: http://git-wip-us.apache.org/repos/asf/incubator-reef/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-reef/commit/64f7e0a0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-reef/tree/64f7e0a0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-reef/diff/64f7e0a0 Branch: refs/heads/master Commit: 64f7e0a036e011b240d5e256537fe8eb362c1f0c Parents: 76d1010 Author: Julia Wang <[email protected]> Authored: Mon Mar 9 12:38:28 2015 -0700 Committer: Julia Wang <[email protected]> Committed: Tue Mar 10 17:51:47 2015 -0700 ---------------------------------------------------------------------- lang/cs/.gitignore | 1 + .../Org.Apache.REEF.Common.Tests.csproj | 75 ++++++++++ .../Properties/AssemblyInfo.cs | 55 ++++++++ .../TestHttpSerialization.cs | 96 +++++++++++++ .../Avro/AvroHttpRequest.cs | 43 +++--- .../Avro/AvroHttpSerializer.cs | 77 ++++++++++ .../Org.Apache.REEF.Common/Avro/HeaderEntry.cs | 58 ++++++++ .../Org.Apache.REEF.Common.csproj | 1 + .../Bridge/HttpServerHandler.cs | 24 +++- .../Bridge/ReefHttpRequest.cs | 4 + ...bridge-0.11.0-incubating-SNAPSHOT-shaded.jar | Bin 12937817 -> 12748678 bytes lang/cs/Org.Apache.REEF.sln | 8 ++ .../reef/javabridge/generic/JobDriver.java | 5 +- .../src/main/avro/webRequest.avsc | 73 ++++++---- .../reef/webserver/AvroHttpSerializer.java | 36 +++++ .../reef/webserver/ParsedHttpRequest.java | 20 +++ .../reef/webserver/TestAvroHttpSerializer.java | 139 ++++++++++++++++++- 17 files changed, 659 insertions(+), 56 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/.gitignore ---------------------------------------------------------------------- diff --git a/lang/cs/.gitignore b/lang/cs/.gitignore index 3da4cf8..cea2523 100644 --- a/lang/cs/.gitignore +++ b/lang/cs/.gitignore @@ -8,5 +8,6 @@ TestResults **/obj **/.nuget/nuspec **/.nuget/packages +*.sln.GhostDoc.xml http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj b/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj new file mode 100644 index 0000000..cfab7bc --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +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 ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Org.Apache.REEF.Common.Tests</RootNamespace> + <AssemblyName>Org.Apache.REEF.Common.Tests</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..</SolutionDir> + <RestorePackages>true</RestorePackages> + </PropertyGroup> + <Import Project="$(SolutionDir)\build.props" /> + <PropertyGroup> + <BuildPackage>false</BuildPackage> + </PropertyGroup> + <ItemGroup> + <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> + </ItemGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="TestHttpSerialization.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="$(SolutionDir)\Org.Apache.REEF.Common\Org.Apache.REEF.Common.csproj"> + <Project>{545a0582-4105-44ce-b99c-b1379514a630}</Project> + <Name>Org.Apache.REEF.Common</Name> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\Org.Apache.REEF.Utilities\Org.Apache.REEF.Utilities.csproj"> + <Project>{79e7f89a-1dfb-45e1-8d43-d71a954aeb98}</Project> + <Name>Org.Apache.REEF.Utilities</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.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. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common.Tests/Properties/AssemblyInfo.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/Properties/AssemblyInfo.cs b/lang/cs/Org.Apache.REEF.Common.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..691b596 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +/** + * 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. + */ + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Org.Apache.REEF.Common.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Org.Apache.REEF.Common.Tests")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("56634b2e-ff34-4c06-99f4-3c1388093e59")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common.Tests/TestHttpSerialization.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/TestHttpSerialization.cs b/lang/cs/Org.Apache.REEF.Common.Tests/TestHttpSerialization.cs new file mode 100644 index 0000000..de2cffd --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/TestHttpSerialization.cs @@ -0,0 +1,96 @@ +/** + * 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. + */ + +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Org.Apache.REEF.Common.Avro; +using Org.Apache.REEF.Utilities; +using Org.Apache.REEF.Utilities.Logging; + +namespace Org.Apache.REEF.Common.Tests +{ + /// <summary> + /// Class TestHttpSerialization. This class contains unit tests for HttpRequest serailization and deserialization. + /// </summary> + [TestClass] + public class TestHttpSerialization + { + private static readonly Logger LOGGER = Logger.GetLogger(typeof(TestHttpSerialization)); + + /// <summary> + /// Tests the HTTP request serialization jason round trip. + /// </summary> + [TestMethod] + public void TestHttpRequestSerializationJasonRoundTrip() + { + AvroHttpRequest r = CreatAvorHttpRequest(); + + string str = AvroHttpSerializer.ToJson(r); + byte[] bytes = ByteUtilities.StringToByteArrays(str); + var r1 = AvroHttpSerializer.FromBytesWithJoson(bytes); + + var ri = ByteUtilities.ByteArrarysToString(r.InputStream); + var ri1 = ByteUtilities.ByteArrarysToString(r1.InputStream); + Assert.AreEqual(ri, ri1); + Assert.AreEqual(r.QueryString, r1.QueryString); + } + + /// <summary> + /// Tests the HTTP request serialization round trip. + /// </summary> + [TestMethod] + public void TestHttpRequestSerializationBytesRoundTrip() + { + AvroHttpRequest r = CreatAvorHttpRequest(); + + var b = AvroHttpSerializer.ToBytes(r); + var r1 = AvroHttpSerializer.FromBytes(b); + + var ri = ByteUtilities.ByteArrarysToString(r.InputStream); + var ri1 = ByteUtilities.ByteArrarysToString(r1.InputStream); + Assert.AreEqual(ri, ri1); + Assert.AreEqual(r.QueryString, r1.QueryString); + } + + /// <summary> + /// Creats an Avor HTTP request for unit tests. + /// </summary> + /// <returns>AvroHttpRequest.</returns> + private AvroHttpRequest CreatAvorHttpRequest() + { + AvroHttpRequest r = new AvroHttpRequest(); + r.Header = new List<HeaderEntry>(); + HeaderEntry he1 = new HeaderEntry(); + he1.key = "a"; + he1.value = "xxx"; + HeaderEntry he2 = new HeaderEntry(); + he2.key = "b"; + he2.value = "yyy"; + r.Header.Add(he1); + r.Header.Add(he2); + + r.HttpMethod = "POST"; + r.InputStream = ByteUtilities.StringToByteArrays("test binary stream data"); + r.PathInfo = "/reef/evaluators"; + r.QueryString = "id=12&id=34&a=b"; + r.RequestUrl = "http://localhost:8080/reef/evaluators?id=12&id=34&a=b"; + return r; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpRequest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpRequest.cs b/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpRequest.cs index 29b9ef7..182992e 100644 --- a/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpRequest.cs +++ b/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpRequest.cs @@ -1,16 +1,19 @@ //<auto-generated /> - -using System.Runtime.Serialization; - namespace Org.Apache.REEF.Common.Avro { + using System; + using System.Collections.Generic; + using System.Runtime.Serialization; + using Microsoft.Hadoop.Avro; + /// <summary> /// Used to serialize and deserialize Avro record org.apache.reef.webserver.AvroHttpRequest. /// </summary> [DataContract(Namespace = "org.apache.reef.webserver")] + [KnownType(typeof(List<Org.Apache.REEF.Common.Avro.HeaderEntry>))] public partial class AvroHttpRequest { - private const string JsonSchema = @"{""type"":""record"",""name"":""org.apache.reef.webserver.AvroHttpRequest"",""fields"":[{""name"":""requestUrl"",""type"":""string""},{""name"":""pathInfo"",""type"":""string""},{""name"":""queryString"",""type"":""string""},{""name"":""httpMethod"",""type"":""string""},{""name"":""inputStream"",""type"":""bytes""}]}"; + private const string JsonSchema = @"{""type"":""record"",""name"":""org.apache.reef.webserver.AvroHttpRequest"",""fields"":[{""name"":""header"",""type"":{""type"":""array"",""items"":{""type"":""record"",""name"":""org.apache.reef.webserver.HeaderEntry"",""fields"":[{""name"":""key"",""type"":""string""},{""name"":""value"",""type"":""string""}]}}},{""name"":""requestUrl"",""type"":""string""},{""name"":""pathInfo"",""type"":""string""},{""name"":""queryString"",""type"":""string""},{""name"":""httpMethod"",""type"":""string""},{""name"":""inputStream"",""type"":""bytes""}]}"; /// <summary> /// Gets the schema. @@ -22,37 +25,43 @@ namespace Org.Apache.REEF.Common.Avro return JsonSchema; } } - + + /// <summary> + /// Gets or sets the header field. + /// </summary> + [DataMember] + public List<Org.Apache.REEF.Common.Avro.HeaderEntry> Header { get; set; } + /// <summary> /// Gets or sets the requestUrl field. /// </summary> [DataMember] public string RequestUrl { get; set; } - + /// <summary> /// Gets or sets the pathInfo field. /// </summary> [DataMember] public string PathInfo { get; set; } - + /// <summary> /// Gets or sets the queryString field. /// </summary> [DataMember] public string QueryString { get; set; } - + /// <summary> /// Gets or sets the httpMethod field. /// </summary> [DataMember] public string HttpMethod { get; set; } - + /// <summary> /// Gets or sets the inputStream field. /// </summary> [DataMember] public byte[] InputStream { get; set; } - + /// <summary> /// Initializes a new instance of the <see cref="AvroHttpRequest"/> class. /// </summary> @@ -63,18 +72,20 @@ namespace Org.Apache.REEF.Common.Avro /// <summary> /// Initializes a new instance of the <see cref="AvroHttpRequest"/> class. /// </summary> + /// <param name="header">The header.</param> /// <param name="requestUrl">The requestUrl.</param> /// <param name="pathInfo">The pathInfo.</param> /// <param name="queryString">The queryString.</param> /// <param name="httpMethod">The httpMethod.</param> /// <param name="inputStream">The inputStream.</param> - public AvroHttpRequest(string requestUrl, string pathInfo, string queryString, string httpMethod, byte[] inputStream) + public AvroHttpRequest(List<Org.Apache.REEF.Common.Avro.HeaderEntry> header, string requestUrl, string pathInfo, string queryString, string httpMethod, byte[] inputStream) { - RequestUrl = requestUrl; - PathInfo = pathInfo; - QueryString = queryString; - HttpMethod = httpMethod; - InputStream = inputStream; + this.Header = header; + this.RequestUrl = requestUrl; + this.PathInfo = pathInfo; + this.QueryString = queryString; + this.HttpMethod = httpMethod; + this.InputStream = inputStream; } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpSerializer.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpSerializer.cs b/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpSerializer.cs index 5a57a5b..6b936f7 100644 --- a/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpSerializer.cs +++ b/lang/cs/Org.Apache.REEF.Common/Avro/AvroHttpSerializer.cs @@ -19,9 +19,14 @@ using System.IO; using Microsoft.Hadoop.Avro; +using Newtonsoft.Json; +using Org.Apache.REEF.Utilities; namespace Org.Apache.REEF.Common.Avro { + /// <summary> + /// Class AvroHttpSerializer. Provides methods to serialize and deserialize HttpRequest + /// </summary> public class AvroHttpSerializer { public static AvroHttpRequest FromBytes(byte[] serializedBytes) @@ -32,5 +37,77 @@ namespace Org.Apache.REEF.Common.Avro return serializer.Deserialize(stream); } } + + /// <summary> + /// Conver bytes which contains Json string into AvroHttpRequest object + /// </summary> + /// <param name="serializedBytes">The serialized bytes.</param> + /// <returns>AvroHttpRequest.</returns> + public static AvroHttpRequest FromBytesWithJoson(byte[] serializedBytes) + { + string s = ByteUtilities.ByteArrarysToString(serializedBytes); + return FromJson(s); + } + + /// <summary> + /// Convert from Json string into AvroHttpRequest object + /// </summary> + /// <param name="josonString">The joson string.</param> + /// <returns>AvroHttpRequest.</returns> + public static AvroHttpRequest FromJson(string josonString) + { + return JsonConvert.DeserializeObject<AvroHttpRequest>(josonString); + } + + /// <summary> + /// Convert from AvroHttpRequest to Json string + /// </summary> + /// <param name="httpRequest">The HTTP request.</param> + /// <returns>System.String.</returns> + public static string ToJson(AvroHttpRequest httpRequest) + { + return JsonConvert.SerializeObject(httpRequest); + } + + /// <summary> + /// Serialize AvroHttpRequest object into bytes + /// </summary> + /// <param name="obj">The object.</param> + /// <returns>System.Byte[].</returns> + public static byte[] ToBytes(AvroHttpRequest obj) + { + var serializer = AvroSerializer.Create<AvroHttpRequest>(); + using (MemoryStream stream = new MemoryStream()) + { + serializer.Serialize(stream, obj); + return stream.GetBuffer(); + } + } + + /// <summary> + /// Deserialize from file to AvroHttpRequest object. + /// </summary> + /// <param name="fileName">Name of the file.</param> + /// <returns>AvroHttpRequest.</returns> + public static AvroHttpRequest FromFile(string fileName) + { + var str = File.ReadAllText(fileName); + AvroHttpRequest avroHttprequest = JsonConvert.DeserializeObject<AvroHttpRequest>(str); + return avroHttprequest; + } + + /// <summary> + /// Serialize AvroHttpRequest in to file + /// </summary> + /// <param name="avroHttprequest">The avro httprequest.</param> + /// <param name="fileName">Name of the file.</param> + public static void ToFile(AvroHttpRequest avroHttprequest, string fileName) + { + var bytes = ToBytes(avroHttprequest); + using (var file = File.OpenWrite(fileName)) + { + file.Write(bytes,0,bytes.Length); + } + } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common/Avro/HeaderEntry.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Avro/HeaderEntry.cs b/lang/cs/Org.Apache.REEF.Common/Avro/HeaderEntry.cs new file mode 100644 index 0000000..6645f32 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/Avro/HeaderEntry.cs @@ -0,0 +1,58 @@ +//<auto-generated /> +namespace Org.Apache.REEF.Common.Avro +{ + using System; + using System.Collections.Generic; + using System.Runtime.Serialization; + using Microsoft.Hadoop.Avro; + + /// <summary> + /// Used to serialize and deserialize Avro record org.apache.reef.webserver.HeaderEntry. + /// </summary> + [DataContract(Namespace = "org.apache.reef.webserver")] + public partial class HeaderEntry + { + private const string JsonSchema = @"{""type"":""record"",""name"":""org.apache.reef.webserver.HeaderEntry"",""fields"":[{""name"":""key"",""type"":""string""},{""name"":""value"",""type"":""string""}]}"; + + /// <summary> + /// Gets the schema. + /// </summary> + public static string Schema + { + get + { + return JsonSchema; + } + } + + /// <summary> + /// Gets or sets the key field. + /// </summary> + [DataMember] + public string key { get; set; } + + /// <summary> + /// Gets or sets the value field. + /// </summary> + [DataMember] + public string value { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="HeaderEntry"/> class. + /// </summary> + public HeaderEntry() + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="HeaderEntry"/> class. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + public HeaderEntry(string key, string value) + { + this.key = key; + this.value = value; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj index b531904..9cb5b72 100644 --- a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj +++ b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj @@ -64,6 +64,7 @@ under the License. <Compile Include="Avro\AvroHttpSerializer.cs" /> <Compile Include="Avro\AvroJsonSerializer.cs" /> <Compile Include="Avro\AvroReefServiceInfo.cs" /> + <Compile Include="Avro\HeaderEntry.cs" /> <Compile Include="Catalog\Capabilities\CPU.cs" /> <Compile Include="Catalog\Capabilities\ICapability.cs" /> <Compile Include="Catalog\Capabilities\RAM.cs" /> http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Driver/Bridge/HttpServerHandler.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Driver/Bridge/HttpServerHandler.cs b/lang/cs/Org.Apache.REEF.Driver/Bridge/HttpServerHandler.cs index 7d56f82..c3b6cae 100644 --- a/lang/cs/Org.Apache.REEF.Driver/Bridge/HttpServerHandler.cs +++ b/lang/cs/Org.Apache.REEF.Driver/Bridge/HttpServerHandler.cs @@ -66,7 +66,7 @@ namespace Org.Apache.REEF.Driver.Bridge } /// <summary> - /// Called when receving an http request from Java side + /// Called when receiving an http request from Java side /// </summary> /// <param name="httpMessage">The HTTP message.</param> public void OnNext(IHttpMessage httpMessage) @@ -84,15 +84,20 @@ namespace Org.Apache.REEF.Driver.Bridge else { LOGGER.Log(Level.Info, "HttpHandler OnNext, handling http request."); - byte[] byteData = httpMessage.GetQueryReuestData(); - AvroHttpRequest avroHttpRequest = AvroHttpSerializer.FromBytes(byteData); - LOGGER.Log(Level.Info, "HttpHandler OnNext, requestData:" + avroHttpRequest); + byte[] byteData = httpMessage.GetQueryReuestData(); + AvroHttpRequest avroHttpRequest = AvroHttpSerializer.FromBytesWithJoson(byteData); + LOGGER.Log(Level.Info, string.Format(CultureInfo.CurrentCulture, "HttpHandler OnNext, requestData:", avroHttpRequest)); string spec = GetSpecification(avroHttpRequest.PathInfo); if (spec != null) { LOGGER.Log(Level.Info, "HttpHandler OnNext, target:" + spec); ReefHttpRequest request = ToHttpRequest(avroHttpRequest); + + foreach (var h in request.Header) + { + LOGGER.Log(Level.Info, string.Format(CultureInfo.CurrentCulture, "HttpRequest Header-key: {0}, value: {1}.", h.Key, h.Value)); + } ReefHttpResponse response = new ReefHttpResponse(); IHttpHandler handler; @@ -108,9 +113,7 @@ namespace Org.Apache.REEF.Driver.Bridge else { responseData = - ByteUtilities.StringToByteArrays(string.Format(CultureInfo.CurrentCulture, - "No event handler found at CLR side for {0}.", - spec)); + ByteUtilities.StringToByteArrays(string.Format(CultureInfo.CurrentCulture, "No event handler found at CLR side for {0}.", spec)); } httpMessage.SetQueryResponseData(responseData); } @@ -154,6 +157,13 @@ namespace Org.Apache.REEF.Driver.Bridge httpRequest.Url = avroRequest.RequestUrl; httpRequest.Querystring = avroRequest.QueryString; + IDictionary<string, string> header = new Dictionary<string, string>(); + foreach (var h in avroRequest.Header) + { + header.Add(h.key, h.value); + } + httpRequest.Header = header; + HttpMethod m; HttpMethod.TryParse(avroRequest.HttpMethod, true, out m); httpRequest.Method = m; http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Driver/Bridge/ReefHttpRequest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Driver/Bridge/ReefHttpRequest.cs b/lang/cs/Org.Apache.REEF.Driver/Bridge/ReefHttpRequest.cs index 97c0465..478e887 100644 --- a/lang/cs/Org.Apache.REEF.Driver/Bridge/ReefHttpRequest.cs +++ b/lang/cs/Org.Apache.REEF.Driver/Bridge/ReefHttpRequest.cs @@ -17,6 +17,8 @@ * under the License. */ +using System.Collections; +using System.Collections.Generic; using System.Globalization; namespace Org.Apache.REEF.Driver.Bridge @@ -41,6 +43,8 @@ namespace Org.Apache.REEF.Driver.Bridge public string PathInfo { get; set; } + public IDictionary<string, string> Header { get; set; } + public string Tostring() { return string.Format(CultureInfo.InvariantCulture, "Url: {0}, query string {1}", Url, Querystring); http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.Tests/bin/reef-bridge-0.11.0-incubating-SNAPSHOT-shaded.jar ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tests/bin/reef-bridge-0.11.0-incubating-SNAPSHOT-shaded.jar b/lang/cs/Org.Apache.REEF.Tests/bin/reef-bridge-0.11.0-incubating-SNAPSHOT-shaded.jar index 72fbf13..c4a6fc7 100644 Binary files a/lang/cs/Org.Apache.REEF.Tests/bin/reef-bridge-0.11.0-incubating-SNAPSHOT-shaded.jar and b/lang/cs/Org.Apache.REEF.Tests/bin/reef-bridge-0.11.0-incubating-SNAPSHOT-shaded.jar differ http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/cs/Org.Apache.REEF.sln ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.sln b/lang/cs/Org.Apache.REEF.sln index cdd8778..d0c3d00 100644 --- a/lang/cs/Org.Apache.REEF.sln +++ b/lang/cs/Org.Apache.REEF.sln @@ -40,6 +40,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Org.Apache.REEF.All", "Org. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Org.Apache.REEF.Examples", "Org.Apache.REEF.Examples\Org.Apache.REEF.Examples.csproj", "{75503F90-7B82-4762-9997-94B5C68F15DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Org.Apache.REEF.Common.Tests", "Org.Apache.REEF.Common.Tests\Org.Apache.REEF.Common.Tests.csproj", "{F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -168,6 +170,12 @@ Global {75503F90-7B82-4762-9997-94B5C68F15DB}.Release|Any CPU.Build.0 = Release|Any CPU {75503F90-7B82-4762-9997-94B5C68F15DB}.Release|x64.ActiveCfg = Release|x64 {75503F90-7B82-4762-9997-94B5C68F15DB}.Release|x64.Build.0 = Release|x64 + {F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}.Debug|x64.ActiveCfg = Debug|Any CPU + {F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}.Release|Any CPU.Build.0 = Release|Any CPU + {F1A3495C-2CBD-4F3B-AEDC-9C1A43D9F238}.Release|x64.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java b/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java index b2e0083..228743b 100644 --- a/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java +++ b/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java @@ -406,7 +406,10 @@ public final class JobDriver { try (final LoggingScope ls = loggingScopeFactory.httpRequest(parsedHttpRequest.getRequestUri())) { final AvroHttpSerializer httpSerializer = new AvroHttpSerializer(); final AvroHttpRequest avroHttpRequest = httpSerializer.toAvro(parsedHttpRequest); - final byte[] requestBytes = httpSerializer.toBytes(avroHttpRequest); + + final String requestString = httpSerializer.toString(avroHttpRequest); + final byte[] requestBytes = requestString.getBytes(); + //final byte[] requestBytes = httpSerializer.toBytes(avroHttpRequest); try { final HttpServerEventBridge httpServerEventBridge = new HttpServerEventBridge(requestBytes); http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/java/reef-webserver/src/main/avro/webRequest.avsc ---------------------------------------------------------------------- diff --git a/lang/java/reef-webserver/src/main/avro/webRequest.avsc b/lang/java/reef-webserver/src/main/avro/webRequest.avsc index 0cf0abc..ec2520c 100644 --- a/lang/java/reef-webserver/src/main/avro/webRequest.avsc +++ b/lang/java/reef-webserver/src/main/avro/webRequest.avsc @@ -1,29 +1,46 @@ /** - * 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. - */ - {"namespace": "org.apache.reef.webserver", - "type": "record", - "name": "AvroHttpRequest", - "fields": [ - {"name": "requestUrl", "type": "string"}, - {"name": "pathInfo", "type": "string"}, - {"name": "queryString", "type": "string"}, - {"name": "httpMethod", "type": "string"}, - {"name": "inputStream", "type": "bytes"} - ] -} +* 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. +*/ + +[ + { + "namespace": "org.apache.reef.webserver", + "type": "record", + "name": "HeaderEntry", + "fields": [ + { "name": "key", "type": "string" }, + { "name": "value", "type": "string" } + ] + }, + { + "namespace": "org.apache.reef.webserver", + "type": "record", + "name": "AvroHttpRequest", + "fields": [ + { + "name": "header", + "type": { "type": "array", "items": "HeaderEntry" } + }, + {"name": "requestUrl", "type": "string"}, + {"name": "pathInfo", "type": "string"}, + {"name": "queryString", "type": "string"}, + {"name": "httpMethod", "type": "string"}, + {"name": "inputStream", "type": "bytes"} + ] + } +] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/AvroHttpSerializer.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/AvroHttpSerializer.java b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/AvroHttpSerializer.java index 18c64f7..f3fe9d9 100644 --- a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/AvroHttpSerializer.java +++ b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/AvroHttpSerializer.java @@ -18,14 +18,18 @@ */ package org.apache.reef.webserver; +import org.apache.avro.file.DataFileReader; +import org.apache.avro.file.DataFileWriter; import org.apache.avro.io.*; import org.apache.avro.specific.SpecificDatumReader; import org.apache.avro.specific.SpecificDatumWriter; import javax.servlet.ServletException; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.*; /** * Serialize Http Request Response data with Avro. @@ -41,12 +45,14 @@ public class AvroHttpSerializer { * Convert from HttpServletRequest to AvroHttpRequest. */ public AvroHttpRequest toAvro(final ParsedHttpRequest parsedRequest) throws ServletException, IOException { + return AvroHttpRequest.newBuilder() .setRequestUrl(parsedRequest.getRequestUrl()) .setHttpMethod(parsedRequest.getMethod()) .setQueryString(parsedRequest.getQueryString()) .setPathInfo(parsedRequest.getPathInfo()) .setInputStream(ByteBuffer.wrap(parsedRequest.getInputStream())) + .setHeader(parsedRequest.getHeaderEntryList()) .build(); } @@ -81,6 +87,36 @@ public class AvroHttpSerializer { } /** + * Conver AvroHttpRequest to a file + * @param avroHttpRequest + * @param file + * @throws IOException + * @throws ServletException + */ + public void toFile(final AvroHttpRequest avroHttpRequest, final File file) throws IOException, ServletException { + final DatumWriter<AvroHttpRequest> httpWriter = new SpecificDatumWriter<>(AvroHttpRequest.class); + try (final DataFileWriter<AvroHttpRequest> dataFileWriter = new DataFileWriter<>(httpWriter)) { + dataFileWriter.create(avroHttpRequest.getSchema(), file); + dataFileWriter.append(avroHttpRequest); + } + } + + /** + * Convert a file to AvroHttpRequest + * @param file + * @return + * @throws IOException + */ + public AvroHttpRequest fromFile(final File file) throws IOException { + final AvroHttpRequest avrohttpRequest; + try (final DataFileReader<AvroHttpRequest> dataFileReader = + new DataFileReader<>(file, new SpecificDatumReader<>(AvroHttpRequest.class))) { + avrohttpRequest = dataFileReader.next(); + } + return avrohttpRequest; + } + + /** * Convert JSON String to AvroHttpRequest. */ public AvroHttpRequest fromString(final String jasonStr) { http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/ParsedHttpRequest.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/ParsedHttpRequest.java b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/ParsedHttpRequest.java index ccf2a85..55138bf 100644 --- a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/ParsedHttpRequest.java +++ b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/ParsedHttpRequest.java @@ -94,6 +94,26 @@ public final class ParsedHttpRequest { } /** + * get http header as a list of HeaderEntry + * @return + */ + public List<HeaderEntry> getHeaderEntryList() { + final List<HeaderEntry> list = new ArrayList<HeaderEntry>(); + final Iterator it = this.headers.entrySet().iterator(); + while (it.hasNext()) { + final Map.Entry pair = (Map.Entry)it.next(); + System.out.println(pair.getKey() + " = " + pair.getValue()); + final HeaderEntry e = HeaderEntry.newBuilder() + .setKey((String) pair.getKey()) + .setValue((String) pair.getValue()) + .build(); + list.add(e); + it.remove(); // avoids a ConcurrentModificationException + } + return list; + } + + /** * get target to match specification like "Reef" * * @return specification http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/64f7e0a0/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestAvroHttpSerializer.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestAvroHttpSerializer.java b/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestAvroHttpSerializer.java index 2ca0683..e85f9a7 100644 --- a/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestAvroHttpSerializer.java +++ b/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestAvroHttpSerializer.java @@ -25,8 +25,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import javax.servlet.ServletException; +import java.io.*; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.util.ArrayList; /** * Test Avro Http Serializer @@ -37,6 +40,20 @@ public final class TestAvroHttpSerializer { private AvroHttpRequest avroRequest; private AvroHttpSerializer avroHttpSerializer; + public static String readStream(InputStream is) { + final StringBuilder sb = new StringBuilder(512); + try { + final Reader r = new InputStreamReader(is, "UTF-8"); + int c = 0; + while ((c = r.read()) != -1) { + sb.append((char) c); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return sb.toString(); + } + @Before public void setUp() throws Exception { final String s = "test binary stream data"; @@ -47,10 +64,81 @@ public final class TestAvroHttpSerializer { .setQueryString("id=12&id=34&a=b") .setPathInfo("/reef/evaluators") .setInputStream(ByteBuffer.wrap(b)) + .setHeader(createHeader()) .build(); avroHttpSerializer = new AvroHttpSerializer(); } + /** + * Test serialize to file then deserialize from file + * @throws IOException + * @throws ServletException + */ + @Test + public void testFileRoundTrip() throws IOException, ServletException { + final File f = new File("httpRequestData.bin"); + avroHttpSerializer.toFile(avroRequest, f); + final AvroHttpRequest avroRequest2 = avroHttpSerializer.fromFile(f); + f.delete(); + assertEqual(avroRequest, avroRequest2); + } + + + /** + * Test serialize to bytes, then write to file, then read from file, finally deserialize + * @throws IOException + * @throws ServletException + */ + @Test + public void testFile1RoundTrip() throws IOException, ServletException { + final byte[] bytes = avroHttpSerializer.toBytes(avroRequest); + final File f = new File("httpRequestData.bin"); + final OutputStream os = new FileOutputStream(f); + os.write(bytes, 0, bytes.length); + os.close(); + + //final File f = new File("httpRequestData.bin"); + final byte[] bytes1 = new byte[(int) f.length()]; + final InputStream is = new FileInputStream("httpRequestData.bin"); + is.read(bytes1, 0, bytes1.length); + + is.close(); + f.delete(); + final AvroHttpRequest deserializedRequest = avroHttpSerializer.fromBytes(bytes1); + + assertEqual(avroRequest, deserializedRequest); + } + + /** + * Test serialize to string, then write to file, then read from file, finally deserialize + * @throws IOException + * @throws ServletException + */ + @Test + public void testFile2RoundTrip() throws IOException, ServletException { + final String serializedString = avroHttpSerializer.toString(avroRequest); + + final File f = new File("httpRequestData.txt"); + final OutputStream os = new FileOutputStream(f);//"httpRequestData.txt"); + final OutputStreamWriter sw = new OutputStreamWriter(os); + sw.write(serializedString); + sw.flush(); + sw.close(); + os.close(); + + final InputStream is = new FileInputStream(f); + final String all = readStream(is); + is.close(); + f.delete(); + + final AvroHttpRequest deserializedRequest = avroHttpSerializer.fromString(all); + + assertEqual(avroRequest, deserializedRequest); + } + + /** + * Test serialize to JSon string, the deserialize from it + */ @Test public void testJSonsStringRoundTrip() { final String serializedString = avroHttpSerializer.toString(avroRequest); @@ -58,6 +146,9 @@ public final class TestAvroHttpSerializer { assertEqual(avroRequest, deserializedRequest); } + /** + * Test serialize to bytes, the deserialize from it + */ @Test public void testBytesRoundTrip() { final byte[] serializedBytes = avroHttpSerializer.toBytes(avroRequest); @@ -73,25 +164,31 @@ public final class TestAvroHttpSerializer { Assert.assertEquals(request1.getInputStream(), request2.getInputStream()); } + /** + * Test null incomplete request + */ @Test public void testIncompleteData() { thrown.expect(AvroRuntimeException.class); - thrown.expectMessage("Field queryString type:STRING pos:2 not set and has no default value"); + thrown.expectMessage("Field queryString type:STRING pos:3 not set and has no default value"); final String s = "test binary stream data"; final byte[] b = s.getBytes(Charset.forName("UTF-8")); avroRequest = AvroHttpRequest.newBuilder() .setRequestUrl("http://localhost:8080/reef/evaluators?id=12&id=34&a=b") .setHttpMethod("POST") - //.setQueryString("id=12&id=34&a=b") .setPathInfo("/reef/evaluators") .setInputStream(ByteBuffer.wrap(b)) + .setHeader(createHeader()) .build(); } + /** + * Test null query string + */ @Test public void testNullData() { thrown.expect(AvroRuntimeException.class); - thrown.expectMessage("Field queryString type:STRING pos:2 does not accept null values"); + thrown.expectMessage("Field queryString type:STRING pos:3 does not accept null values"); final String s = "test binary stream data"; final byte[] b = s.getBytes(Charset.forName("UTF-8")); avroRequest = AvroHttpRequest.newBuilder() @@ -99,55 +196,89 @@ public final class TestAvroHttpSerializer { .setHttpMethod("POST") .setQueryString(null) .setPathInfo("/reef/evaluators") + .setHeader(createHeader()) .setInputStream(ByteBuffer.wrap(b)) .build(); } + /** + * Test null bytes + */ @Test public void testNullBytes() { thrown.expect(AvroRuntimeException.class); - thrown.expectMessage("Field inputStream type:BYTES pos:4 does not accept null values"); + thrown.expectMessage("Field inputStream type:BYTES pos:5 does not accept null values"); final String s = "test binary stream data"; final byte[] b = s.getBytes(Charset.forName("UTF-8")); + avroRequest = AvroHttpRequest.newBuilder() .setRequestUrl("http://localhost:8080/reef/evaluators?id=12&id=34&a=b") .setHttpMethod("POST") .setQueryString("id=12&id=34&a=b") .setPathInfo("/reef/evaluators") .setInputStream(null) + .setHeader(createHeader()) .build(); } + /** + * Test empty string + */ @Test public void testEmptyString() { final String s = "test binary stream data"; final byte[] b = s.getBytes(Charset.forName("UTF-8")); + avroRequest = AvroHttpRequest.newBuilder() .setRequestUrl("http://localhost:8080/reef/evaluators?id=12&id=34&a=b") .setHttpMethod("POST") .setQueryString("") .setPathInfo("/reef/evaluators") .setInputStream(ByteBuffer.wrap(b)) + .setHeader(createHeader()) .build(); + avroHttpSerializer = new AvroHttpSerializer(); final byte[] serializedBytes = avroHttpSerializer.toBytes(avroRequest); final AvroHttpRequest deserializedRequest = avroHttpSerializer.fromBytes(serializedBytes); assertEqual(avroRequest, deserializedRequest); } + /** + * Test empty bytes + */ @Test public void testEmptyBytes() { final byte[] b = new byte[0]; + avroRequest = AvroHttpRequest.newBuilder() .setRequestUrl("http://localhost:8080/reef/evaluators?id=12&id=34&a=b") .setHttpMethod("POST") .setQueryString("") .setPathInfo("/reef/evaluators") .setInputStream(ByteBuffer.wrap(b)) + .setHeader(createHeader()) .build(); avroHttpSerializer = new AvroHttpSerializer(); final byte[] serializedBytes = avroHttpSerializer.toBytes(avroRequest); final AvroHttpRequest deserializedRequest = avroHttpSerializer.fromBytes(serializedBytes); assertEqual(avroRequest, deserializedRequest); } + + private ArrayList<HeaderEntry> createHeader() { + final ArrayList<HeaderEntry> list = new ArrayList<HeaderEntry>(); + final HeaderEntry e1 = HeaderEntry.newBuilder() + .setKey("a") + .setValue("xxx") + .build(); + list.add(e1); + + final HeaderEntry e2 = HeaderEntry.newBuilder() + .setKey("b") + .setValue("yyy") + .build(); + list.add(e2); + + return list; + } }
