summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/Rebus/App.config33
-rw-r--r--contrib/Rebus/Program.cs81
-rw-r--r--contrib/Rebus/Properties/AssemblyInfo.cs38
-rw-r--r--contrib/Rebus/README.md21
-rw-r--r--contrib/Rebus/RebusSample.csproj102
-rw-r--r--contrib/Rebus/RebusSample.sln28
-rw-r--r--contrib/Rebus/ServiceImpl/Both.cs35
-rw-r--r--contrib/Rebus/ServiceImpl/Client.cs157
-rw-r--r--contrib/Rebus/ServiceImpl/Server.cs143
-rw-r--r--contrib/Rebus/sample.thrift30
-rw-r--r--contrib/Stomp/README.md18
-rw-r--r--contrib/Stomp/Thrift.Transport.STOMP.pas200
-rw-r--r--contrib/Vagrantfile66
-rwxr-xr-xcontrib/async-test/test-leaf.py15
-rw-r--r--contrib/fb303/README.md (renamed from contrib/fb303/README)0
-rw-r--r--contrib/fb303/TClientInfo.cpp3
-rw-r--r--contrib/fb303/TClientInfo.h2
-rw-r--r--contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4134
-rw-r--r--contrib/fb303/aclocal/ax_javac_and_java.m42
-rw-r--r--contrib/fb303/configure.ac1
-rw-r--r--contrib/fb303/cpp/FacebookBase.cpp2
-rw-r--r--contrib/fb303/cpp/FacebookBase.h1
-rw-r--r--contrib/fb303/cpp/ServiceTracker.cpp2
-rw-r--r--contrib/fb303/if/fb303.thrift1
-rw-r--r--contrib/fb303/java/build.properties5
-rwxr-xr-xcontrib/fb303/java/build.xml34
-rw-r--r--contrib/fb303/py/fb303/FacebookBase.py77
-rw-r--r--contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py70
-rw-r--r--contrib/fb303/py/setup.py43
-rwxr-xr-xcontrib/mingw-cross-compile.sh15
-rwxr-xr-xcontrib/parse_profiling.py14
-rw-r--r--contrib/thrift-maven-plugin/pom.xml92
-rw-r--r--contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/AbstractThriftMojo.java380
-rw-r--r--contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/Thrift.java262
-rw-r--r--contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftCompileMojo.java78
-rw-r--r--contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftTestCompileMojo.java93
-rw-r--r--contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestAbstractThriftMojo.java102
-rw-r--r--contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestThrift.java163
-rw-r--r--contrib/thrift-maven-plugin/src/test/resources/idl/shared.thrift36
-rw-r--r--contrib/thrift-maven-plugin/src/test/resources/idl/tutorial.thrift152
-rw-r--r--contrib/thrift.el32
-rw-r--r--contrib/thrift.spec79
-rw-r--r--contrib/thrift.vim4
-rw-r--r--contrib/transport-sample/README.md (renamed from contrib/transport-sample/README.txt)0
-rw-r--r--contrib/transport-sample/ThriftCommon.h2
-rw-r--r--contrib/vagrant/centos-6.5/README.md61
-rw-r--r--contrib/vagrant/centos-6.5/Vagrantfile274
-rw-r--r--contrib/zeromq/Makefile8
-rw-r--r--contrib/zeromq/README.md (renamed from contrib/zeromq/README)0
-rw-r--r--contrib/zeromq/TZmqClient.cpp7
-rw-r--r--contrib/zeromq/TZmqClient.h8
-rw-r--r--contrib/zeromq/TZmqClient.py81
-rw-r--r--contrib/zeromq/TZmqServer.cpp6
-rw-r--r--contrib/zeromq/TZmqServer.h5
-rw-r--r--contrib/zeromq/TZmqServer.py87
-rw-r--r--contrib/zeromq/csharp/AssemblyInfo.cs12
-rw-r--r--contrib/zeromq/csharp/TZmqClient.cs2
-rwxr-xr-xcontrib/zeromq/csharp/ThriftZMQ.csproj182
-rwxr-xr-xcontrib/zeromq/csharp/ThriftZMQ.sln84
-rw-r--r--contrib/zeromq/test-client.cpp4
-rwxr-xr-xcontrib/zeromq/test-client.py40
-rw-r--r--contrib/zeromq/test-receiver.cpp2
-rw-r--r--contrib/zeromq/test-sender.cpp2
-rw-r--r--contrib/zeromq/test-server.cpp4
-rwxr-xr-xcontrib/zeromq/test-server.py32
65 files changed, 3284 insertions, 465 deletions
diff --git a/contrib/Rebus/App.config b/contrib/Rebus/App.config
new file mode 100644
index 000000000..4208af6b2
--- /dev/null
+++ b/contrib/Rebus/App.config
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<configuration>
+
+ <configSections>
+ <section name="rebus" type="Rebus.Configuration.RebusConfigurationSection, Rebus"/>
+ </configSections>
+
+ <rebus inputQueue="MyResponses" errorQueue="MyErrors" workers="1">
+ <endpoints>
+ <add messages="RebusSample.MathRequestCall, RebusSample" endpoint="MathRequests"/>
+ <add messages="RebusSample.MathResponseCall, RebusSample" endpoint="MathResponses"/>
+ </endpoints>
+ </rebus>
+
+ <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
diff --git a/contrib/Rebus/Program.cs b/contrib/Rebus/Program.cs
new file mode 100644
index 000000000..563c62ad5
--- /dev/null
+++ b/contrib/Rebus/Program.cs
@@ -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.
+ */
+
+using Rebus.Configuration;
+using Rebus.RabbitMQ;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using RebusSample.Client;
+using RebusSample.Server;
+
+namespace RebusSample
+{
+ class Program
+ {
+ static BuiltinContainerAdapter StartRequestServer(string server)
+ {
+ // client Rebus configuration
+ var adapter = new BuiltinContainerAdapter();
+ Configure.With(adapter)
+ .Transport(t => t.UseRabbitMq("amqp://" + server, "MathRequests", "MathRequestErrors"))
+ .MessageOwnership(o => o.FromRebusConfigurationSection())
+ .CreateBus().Start();
+
+ // register all relevant message handlers
+ adapter.Register(typeof(MathRequestCallHandler));
+ return adapter;
+ }
+
+
+ static BuiltinContainerAdapter StartResponseServer(string server)
+ {
+ // client Rebus configuration
+ var adapter = new BuiltinContainerAdapter();
+ Configure.With(adapter)
+ .Transport(t => t.UseRabbitMq("amqp://" + server, "MathResponses", "MathResponseErrors"))
+ .MessageOwnership(o => o.FromRebusConfigurationSection())
+ .CreateBus().Start();
+
+ // register all relevant message handlers
+ adapter.Register(typeof(MathResponseCallHandler));
+ return adapter;
+ }
+
+ static void Main(string[] args)
+ {
+ string server = "localhost";
+
+ // start all servers
+ var req = StartRequestServer(server);
+ var rsp = StartResponseServer(server);
+
+ // send the first message
+ var random = new Random();
+ var client = new MathRequestClient(server);
+ client.DoTheMath(random.Next(), random.Next());
+
+ // now what?
+ Console.Write("Hit <ENTER> to stop ... ");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/contrib/Rebus/Properties/AssemblyInfo.cs b/contrib/Rebus/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..e476eab76
--- /dev/null
+++ b/contrib/Rebus/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+/**
+ * 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;
+
+[assembly: AssemblyTitle("RebusSample")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RebusSample")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("0af10984-40d3-453d-b1e5-421529e8c7e2")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/contrib/Rebus/README.md b/contrib/Rebus/README.md
new file mode 100644
index 000000000..bbb9c496e
--- /dev/null
+++ b/contrib/Rebus/README.md
@@ -0,0 +1,21 @@
+Sample code for the combination of Thrift with Rebus.
+
+Rebus is a .NET service bus, similar to NServiceBus, but more lightweight.
+It ihas been mainly written by Mogens Heller Grabe and is currently hosted
+on GitHub (https://github.com/rebus-org/Rebus)
+
+As with all ServiceBus or MQ scenarios, due to the highly asynchronous
+operations it is recommended to do all calls as "oneway void" calls.
+
+The configuration can be done via App.Config, via code or even mixed from
+both locations. Refer to the Rebus documentation for further details. For
+this example, since we are effectively implementing two queue listeners in
+only one single process, we do configuration of incoming and error queues
+in the code.
+
+If you want to communicate with non-NET languages, you may need a customized
+serializer as well, in order to override Rebus' default wire format. Please
+refer to the Rebus docs on how to do that (it's not that hard, really).
+
+Additional requirements:
+- RabbitMQ .NET client (see nuget)
diff --git a/contrib/Rebus/RebusSample.csproj b/contrib/Rebus/RebusSample.csproj
new file mode 100644
index 000000000..4058a6da2
--- /dev/null
+++ b/contrib/Rebus/RebusSample.csproj
@@ -0,0 +1,102 @@
+<?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>{264E2126-EDE0-4B47-89C1-B397B25BB13D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RebusSample</RootNamespace>
+ <AssemblyName>RebusSample</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="RabbitMQ.Client">
+ <HintPath>..\..\..\..\..\Toolbox\ServiceBus\3rdparty\rabbitmq-dotnet-client-3.2.1-dotnet-3.0\bin\RabbitMQ.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="Rebus">
+ <HintPath>..\..\..\..\..\Toolbox\ServiceBus\3rdparty\Rebus-master\deploy\NET40\Rebus.dll</HintPath>
+ </Reference>
+ <Reference Include="Rebus.RabbitMQ">
+ <HintPath>..\..\..\..\..\Toolbox\ServiceBus\3rdparty\Rebus-master\deploy\NET40\Rebus.RabbitMQ.dll</HintPath>
+ </Reference>
+ <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="gen-csharp\BasicMathClient.cs" />
+ <Compile Include="gen-csharp\BasicMathServer.cs" />
+ <Compile Include="ServiceImpl\Both.cs" />
+ <Compile Include="ServiceImpl\Client.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ServiceImpl\Server.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup>
+ <ProjectReference Include="..\..\lib\csharp\src\Thrift.csproj">
+ <Project>{499eb63c-d74c-47e8-ae48-a2fc94538e9d}</Project>
+ <Name>Thrift</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>cd $(ProjectDir)
+if not exist gen-csharp\*.cs thrift -gen csharp sample.thrift
+</PreBuildEvent>
+ </PropertyGroup>
+ <!-- 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
diff --git a/contrib/Rebus/RebusSample.sln b/contrib/Rebus/RebusSample.sln
new file mode 100644
index 000000000..284ef36a7
--- /dev/null
+++ b/contrib/Rebus/RebusSample.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.30110.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RebusSample", "RebusSample.csproj", "{264E2126-EDE0-4B47-89C1-B397B25BB13D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/Rebus/ServiceImpl/Both.cs b/contrib/Rebus/ServiceImpl/Both.cs
new file mode 100644
index 000000000..fba67ec15
--- /dev/null
+++ b/contrib/Rebus/ServiceImpl/Both.cs
@@ -0,0 +1,35 @@
+/**
+ * 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;
+
+
+namespace RebusSample
+{
+ // generic data container for serialized Thrift calls
+ public class GenericThriftServiceCall
+ {
+ public byte[] rawBytes;
+ }
+
+ // specific containers (one per Thrift service) to leverage Rebus' handler routing
+ public class MathRequestCall : GenericThriftServiceCall { }
+ public class MathResponseCall : GenericThriftServiceCall { }
+
+} \ No newline at end of file
diff --git a/contrib/Rebus/ServiceImpl/Client.cs b/contrib/Rebus/ServiceImpl/Client.cs
new file mode 100644
index 000000000..2408041a9
--- /dev/null
+++ b/contrib/Rebus/ServiceImpl/Client.cs
@@ -0,0 +1,157 @@
+/**
+ * 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 Rebus;
+using Rebus.Configuration;
+using Rebus.Messages;
+using Rebus.RabbitMQ;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+/*
+ * The client emits calls to BasicMathServers
+ *
+ * The client implements the BasicMathClient service.
+ * If the server has processed our request, we get the results back through this service
+ */
+
+namespace RebusSample.Client
+{
+
+ // handler to be registered with Rebus
+ class MathResponseCallHandler : IHandleMessages<MathResponseCall>
+ {
+ public void Handle(MathResponseCall message)
+ {
+ // Thrift protocol/transport stack
+ var stm = new MemoryStream(message.rawBytes);
+ var trns = new TStreamTransport(stm, null);
+ var prot = new TBinaryProtocol(trns);
+
+ // create a processor and let him handle the call
+ var hndl = new MathResponsesHandler();
+ var proc = new BasicMathClient.Processor(hndl);
+ proc.Process(prot, null); // oneway only
+ }
+ }
+
+
+ // serves incoming responses with calculation results
+ internal class MathResponsesHandler : BasicMathClient.Iface
+ {
+ public void FourResults(int added, int multiplied, int subtracted, int divided)
+ {
+ Console.WriteLine("added = {0}", added);
+ Console.WriteLine("multiplied= {0}", multiplied);
+ Console.WriteLine("subtracted = {0}", subtracted);
+ Console.WriteLine("divided = {0}", divided);
+
+ PingAndDoAnotherCalculation();
+ }
+
+
+ public void ThreeResults(int added, int multiplied, int subtracted)
+ {
+ Console.WriteLine("added = {0}", added);
+ Console.WriteLine("multiplied= {0}", multiplied);
+ Console.WriteLine("subtracted = {0}", subtracted);
+ Console.WriteLine("DIV/0 error during division");
+
+ PingAndDoAnotherCalculation();
+ }
+
+
+ public void Pong(long value)
+ {
+ var latency = DateTime.Now.Ticks - value;
+ Console.WriteLine("Ping took {0} ms", new DateTime(latency).Millisecond);
+ }
+
+
+ private void PingAndDoAnotherCalculation()
+ {
+ var random = new Random();
+ var client = new MathRequestClient("localhost");
+ client.Ping(DateTime.Now.Ticks);
+ client.DoTheMath(random.Next(), random.Next());
+ }
+ }
+
+
+ // provides the client-side interface for calculation requests
+ internal class MathRequestClient : BasicMathServer.Iface
+ {
+ private BuiltinContainerAdapter MQAdapter;
+
+
+ public MathRequestClient(string server)
+ {
+ MQAdapter = new BuiltinContainerAdapter();
+ Configure.With(MQAdapter)
+ .Transport(t => t.UseRabbitMqInOneWayMode("amqp://" + server)) // we need send only
+ .MessageOwnership(o => o.FromRebusConfigurationSection())
+ .CreateBus().Start();
+ }
+
+
+ public void SerializeThriftCall(Action<BasicMathServer.Iface> action)
+ {
+ // Thrift protocol/transport stack
+ var stm = new MemoryStream();
+ var trns = new TStreamTransport(null, stm);
+ var prot = new TBinaryProtocol(trns);
+
+ // serialize the call into a bunch of bytes
+ var client = new BasicMathServer.Client(prot);
+ if( action != null)
+ action(client);
+ else
+ throw new ArgumentException("action must not be null");
+
+ // make sure everything is written to the MemoryStream
+ trns.Flush();
+
+ // send the message
+ var msg = new MathRequestCall() { rawBytes = stm.ToArray() };
+ MQAdapter.Bus.Send(msg);
+ }
+
+
+ public void Ping(long value)
+ {
+ SerializeThriftCall(client =>
+ {
+ client.Ping(value);
+ });
+ }
+
+
+ public void DoTheMath( int arg1, int arg2)
+ {
+ SerializeThriftCall(client =>
+ {
+ client.DoTheMath(arg1, arg2);
+ });
+ }
+ }
+}
+
diff --git a/contrib/Rebus/ServiceImpl/Server.cs b/contrib/Rebus/ServiceImpl/Server.cs
new file mode 100644
index 000000000..149d513c6
--- /dev/null
+++ b/contrib/Rebus/ServiceImpl/Server.cs
@@ -0,0 +1,143 @@
+/**
+ * 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 Rebus;
+using Rebus.Configuration;
+using Rebus.Messages;
+using Rebus.RabbitMQ;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+/*
+ * The server implements the BasicMathServer service .
+ * All results are sent back to the client via the BasicMathClient service
+ */
+
+
+namespace RebusSample.Server
+{
+ // handler to be registered with Rebus
+ class MathRequestCallHandler : IHandleMessages<MathRequestCall>
+ {
+ public void Handle(MathRequestCall message)
+ {
+ // Thrift protocol/transport stack
+ var stm = new MemoryStream(message.rawBytes);
+ var trns = new TStreamTransport(stm, null);
+ var prot = new TBinaryProtocol(trns);
+
+ // create a processor and let him handle the call
+ var hndl = new MathRequestsHandler();
+ var proc = new BasicMathServer.Processor(hndl);
+ proc.Process(prot, null); // oneway only
+ }
+ }
+
+
+ // serves incoming calculation requests
+ internal class MathRequestsHandler : BasicMathServer.Iface
+ {
+ public void Ping(long value)
+ {
+ var client = new MathResponseClient("localhost");
+ client.Pong(value);
+ }
+
+
+ public void DoTheMath(int arg1, int arg2)
+ {
+ var client = new MathResponseClient("localhost");
+ if( arg2 != 0)
+ client.FourResults( arg1+arg2, arg1*arg2, arg1-arg2, arg1/arg2);
+ else
+ client.ThreeResults( arg1+arg2, arg1*arg2, arg1-arg2);
+ }
+ }
+
+
+ // provides the client-side interface for calculation responses
+ internal class MathResponseClient : BasicMathClient.Iface
+ {
+ private BuiltinContainerAdapter MQAdapter;
+
+
+ public MathResponseClient(string server)
+ {
+ MQAdapter = new BuiltinContainerAdapter();
+ Configure.With(MQAdapter)
+ .Transport(t => t.UseRabbitMqInOneWayMode("amqp://" + server)) // we need send only
+ .MessageOwnership(o => o.FromRebusConfigurationSection())
+ .CreateBus().Start();
+ }
+
+
+ public void SerializeThriftCall(Action<BasicMathClient.Iface> action)
+ {
+ // Thrift protocol/transport stack
+ var stm = new MemoryStream();
+ var trns = new TStreamTransport(null, stm);
+ var prot = new TBinaryProtocol(trns);
+
+ // serialize the call into a bunch of bytes
+ var client = new BasicMathClient.Client(prot);
+ if (action != null)
+ action(client);
+ else
+ throw new ArgumentException("action must not be null");
+
+ // make sure everything is written to the MemoryStream
+ trns.Flush();
+
+ // send the message
+ var msg = new MathResponseCall() { rawBytes = stm.ToArray() };
+ MQAdapter.Bus.Send(msg);
+ }
+
+
+ public void Pong(long value)
+ {
+ SerializeThriftCall(client =>
+ {
+ client.Pong(value);
+ });
+ }
+
+
+ public void ThreeResults(int added, int multiplied, int suctracted)
+ {
+ SerializeThriftCall(client =>
+ {
+ client.ThreeResults(added, multiplied, suctracted);
+ });
+ }
+
+
+ public void FourResults(int added, int multiplied, int suctracted, int divided)
+ {
+ SerializeThriftCall(client =>
+ {
+ client.FourResults(added, multiplied, suctracted, divided);
+ });
+ }
+ }
+}
+
diff --git a/contrib/Rebus/sample.thrift b/contrib/Rebus/sample.thrift
new file mode 100644
index 000000000..785e2d38f
--- /dev/null
+++ b/contrib/Rebus/sample.thrift
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+
+service BasicMathServer {
+ oneway void DoTheMath( 1: i32 arg1, 2: i32 arg2)
+ oneway void Ping(1: i64 value)
+}
+
+service BasicMathClient {
+ oneway void ThreeResults( 1 : i32 added, 2 : i32 multiplied, 3 : i32 subtracted);
+ oneway void FourResults( 1 : i32 added, 2 : i32 multiplied, 3 : i32 subtracted, 4 : i32 divided);
+ oneway void Pong(1: i64 value)
+}
diff --git a/contrib/Stomp/README.md b/contrib/Stomp/README.md
new file mode 100644
index 000000000..2e5f21cbf
--- /dev/null
+++ b/contrib/Stomp/README.md
@@ -0,0 +1,18 @@
+Sample code for STOMP-based Thrift clients and/or servers.
+
+Although the sample Thrift STOMP Transport is written in
+Delphi/Pascal, it can easily serve as a starting point for
+similar implementations in other languages.
+
+STOMP is a protocol widely supported by many messaging systems,
+such as Apache ActiveMQ, RabbitMQ and many others. In particular,
+it can be used to communicate with Service-Bus products like Rebus
+or NServiceBus, when running against a STOMP-capable MQ system.
+
+A prerequisite for this sample is the Delphi STOMP Adapter written
+by Daniele Teti (http://www.danieleteti.it/stomp-client), currently
+hosted at Google Code (http://code.google.com/p/delphistompclient).
+
+At the time of writing, the STOMP adapter does not fully support
+binary data. Please check whether this has been fixed, otherwise
+you have to use the JSON protocol (or to fix it on your own).
diff --git a/contrib/Stomp/Thrift.Transport.STOMP.pas b/contrib/Stomp/Thrift.Transport.STOMP.pas
new file mode 100644
index 000000000..7dfb3763c
--- /dev/null
+++ b/contrib/Stomp/Thrift.Transport.STOMP.pas
@@ -0,0 +1,200 @@
+(*
+ * 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.
+ *)
+
+unit Thrift.Transport.STOMP;
+
+interface
+
+uses
+ Classes,Windows, SysUtils,
+ Thrift,
+ Thrift.Transport,
+ Thrift.Protocol,
+ Thrift.Stream,
+ StompClient,
+ StompTypes;
+
+type
+ TStompTransportImpl = class( TStreamTransportImpl)
+ strict private
+ FData : TStringStream;
+ FServer : string;
+ FOutQueue : string;
+ FStompCli : IStompClient;
+ protected
+ function GetIsOpen: Boolean; override;
+ function Peek: Boolean; override;
+ public
+ constructor Create( const aServerAndPort, aOutQueue : string);
+ destructor Destroy; override;
+
+ procedure Open(); override;
+ procedure Close(); override;
+ procedure Flush; override;
+ end;
+
+
+ TStompServerTransportImpl = class( TServerTransportImpl)
+ strict private
+ FServer : string;
+ FInQueue : string;
+ FClient : IStompClient;
+ protected
+ procedure Listen; override;
+ procedure Close; override;
+ function Accept( const fnAccepting: TProc): ITransport; override;
+ public
+ constructor Create( const aServerAndPort, aInQueue : string);
+ destructor Destroy; override;
+ end;
+
+
+const
+ QUEUE_PREFIX = '/queue/';
+ TOPIC_PREFIX = '/topic/';
+ EXCHANGE_PREFIX = '/exchange/';
+
+
+implementation
+
+
+
+constructor TStompTransportImpl.Create( const aServerAndPort, aOutQueue : string);
+var adapter : IThriftStream;
+begin
+ FData := TStringStream.Create;
+ FServer := aServerAndPort;
+ FOutQueue := aOutQueue;
+
+ adapter := TThriftStreamAdapterDelphi.Create( FData, FALSE);
+ inherited Create( nil, adapter); // output only
+end;
+
+
+destructor TStompTransportImpl.Destroy;
+begin
+ inherited Destroy;
+ FreeAndNil( FData);
+ FStompCli := nil;
+end;
+
+
+function TStompTransportImpl.GetIsOpen: Boolean;
+begin
+ result := (FStompCli <> nil);
+end;
+
+
+function TStompTransportImpl.Peek: Boolean;
+begin
+ result := FALSE; // output only
+end;
+
+
+procedure TStompTransportImpl.Open;
+begin
+ if FStompCli <> nil
+ then raise TTransportException.Create( TTransportException.TExceptionType.AlreadyOpen, 'already open')
+ else FStompCli := StompUtils.NewStomp( FServer);
+end;
+
+
+procedure TStompTransportImpl.Close;
+begin
+ FStompCli := nil;
+ FData.Clear;
+end;
+
+
+procedure TStompTransportImpl.Flush;
+begin
+ if FStompCli = nil
+ then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen, 'not open');
+
+ FStompCli.Send( FOutQueue, FData.DataString);
+ FData.Clear;
+end;
+
+
+//--- TStompServerTransportImpl --------------------------------------------
+
+
+constructor TStompServerTransportImpl.Create( const aServerAndPort, aInQueue : string);
+begin
+ inherited Create;
+ FServer := aServerAndPort;
+ FInQueue := aInQueue;
+end;
+
+
+destructor TStompServerTransportImpl.Destroy;
+begin
+ try
+ Close;
+ finally
+ inherited Destroy;
+ end;
+end;
+
+
+procedure TStompServerTransportImpl.Listen;
+begin
+ FClient := StompUtils.NewStomp(FServer);
+ FClient.Subscribe( FInQueue);
+end;
+
+
+procedure TStompServerTransportImpl.Close;
+begin
+ if FClient <> nil then begin
+ FClient.Unsubscribe( FInQueue);
+ FClient := nil;
+ end;
+end;
+
+
+function TStompServerTransportImpl.Accept( const fnAccepting: TProc): ITransport;
+var frame : IStompFrame;
+ adapter : IThriftStream;
+ stream : TStringStream;
+begin
+ if FClient = nil
+ then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
+ 'Not connected.');
+
+ if Assigned(fnAccepting)
+ then fnAccepting();
+
+ try
+ frame := FClient.Receive(MAXINT);
+ if frame = nil then Exit(nil);
+
+ stream := TStringStream.Create( frame.GetBody);
+ adapter := TThriftStreamAdapterDelphi.Create( stream, TRUE);
+ result := TStreamTransportImpl.Create( adapter, nil);
+
+ except
+ on E: Exception
+ do raise TTransportException.Create( E.ToString );
+ end;
+end;
+
+
+end.
+
diff --git a/contrib/Vagrantfile b/contrib/Vagrantfile
index fd6782184..ff53316bb 100644
--- a/contrib/Vagrantfile
+++ b/contrib/Vagrantfile
@@ -22,54 +22,75 @@
$build_and_test = <<SCRIPT
echo "Provisioning system to compile and test Apache Thrift."
-sudo apt-get update -qq -y
-sudo apt-get upgrade -qq -y
+
+# Create swap space
+sudo fallocate -l 2G /swapfile
+sudo chmod 600 /swapfile
+sudo mkswap /swapfile
+sudo swapon /swapfile
+sudo swapon -s
+
+# Update the system
+sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq -y
+sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -qq -y
# Install Dependencies
# ---
# General dependencies
-sudo apt-get install -qq libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev make libqt4-dev git debhelper
+sudo apt-get install -qq automake libtool flex bison pkg-config g++ libssl-dev make libqt4-dev git debhelper
+
+# C++ dependencies
+sudo apt-get install -qq libboost-dev libboost-test-dev libboost-program-options-dev libboost-filesystem-dev libboost-system-dev libevent-dev
# Java dependencies
-sudo apt-get install -qq ant openjdk-7-jdk libcommons-lang3-java
+sudo apt-get install -qq ant openjdk-8-jdk maven
# Python dependencies
-sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools
+sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-six python3-six
# Ruby dependencies
-sudo apt-get install -qq ruby rubygems
+sudo apt-get install -qq ruby ruby-dev
sudo gem install bundler rake
# Perl dependencies
-sudo apt-get install -qq libbit-vector-perl
+sudo apt-get install -qq libbit-vector-perl libclass-accessor-class-perl
# Php dependencies
-sudo apt-get install -qq php5 php5-dev php5-cli php-pear
+sudo apt-get install -qq php5 php5-dev php5-cli php-pear re2c
# GlibC dependencies
sudo apt-get install -qq libglib2.0-dev
# Erlang dependencies
-sudo apt-get install -qq erlang-base erlang-eunit erlang-dev
+sudo apt-get install -qq erlang-base erlang-eunit erlang-dev erlang-tools
# GO dependencies
echo "golang-go golang-go/dashboard boolean false" | debconf-set-selections
sudo apt-get -y install -qq golang golang-go
# Haskell dependencies
-sudo apt-get install -qq ghc6 cabal-install libghc6-binary-dev libghc6-network-dev libghc6-http-dev libghc-hashable-dev libghc-unordered-containers-dev libghc-vector-dev
+sudo apt-get install -qq ghc cabal-install libghc-binary-dev libghc-network-dev libghc-http-dev libghc-hashable-dev libghc-unordered-containers-dev libghc-vector-dev
+sudo cabal update
+
+# Lua dependencies
+sudo apt-get install -qq lua5.2 lua5.2-dev
# Node.js dependencies
-sudo apt-get install -qq npm
+sudo apt-get install -qq nodejs nodejs-dev nodejs-legacy npm
# CSharp
-sudo apt-get install -qq mono-gmcs mono-devel libmono-system-web2.0-cil
-sudo apt-get install -qq mingw32 mingw32-binutils mingw32-runtime
+sudo apt-get install -qq mono-gmcs mono-devel mono-xbuild mono-complete libmono-system-web2.0-cil
+sudo apt-get install -qq mingw32 mingw32-binutils mingw32-runtime nsis
+
+# D dependencies
+sudo wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list
+sudo apt-get update && sudo apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring && sudo apt-get update
+sudo apt-get install -qq xdg-utils dmd-bin
# Customize the system
# ---
-# Default java to latest 1.7 version
-update-java-alternatives -s java-1.7.0-openjdk-amd64
+# Default java to latest 1.8 version
+update-java-alternatives -s java-1.8.0-openjdk-amd64
# PHPUnit package broken in ubuntu. see https://bugs.launchpad.net/ubuntu/+source/phpunit/+bug/701544
sudo apt-get upgrade pear
@@ -87,29 +108,26 @@ date > /etc/vagrant.provisioned
echo "Starting Apache Thrift build..."
cd /thrift
sh bootstrap.sh
-sh configure --without-erlang
+sh configure
make
-make dist
make check
echo "Finished building Apache Thrift."
SCRIPT
Vagrant.configure("2") do |config|
- # Ubuntu 12.04 LTS (Precise Pangolin)
- config.vm.box = "precise64"
- config.vm.box_url = "http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-vagrant-amd64-disk1.box"
- # config.vm.box = "precise32"
- # config.vm.box_url = "http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-vagrant-i386-disk1.box"
+ # Ubuntu 14.04 LTS (Trusty Tahr)
+ config.vm.box = "trusty64"
+ config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
config.vm.synced_folder "../", "/thrift"
config.vm.provider :virtualbox do |vbox|
vbox.customize ["modifyvm", :id, "--memory", "1024"]
vbox.customize ["modifyvm", :id, "--cpus", "2"]
+ vbox.customize ["modifyvm", :id, "--rtcuseutc", "on"]
end
- # call the script
+ # Run the build script to configure the system
config.vm.provision :shell, :inline => $build_and_test
-
end
diff --git a/contrib/async-test/test-leaf.py b/contrib/async-test/test-leaf.py
index 8b7c3e3f5..4ea4a9b8c 100755
--- a/contrib/async-test/test-leaf.py
+++ b/contrib/async-test/test-leaf.py
@@ -7,16 +7,17 @@ from thrift.protocol import TBinaryProtocol
from thrift.server import THttpServer
from aggr import Aggr
+
class AggrHandler(Aggr.Iface):
- def __init__(self):
- self.values = []
+ def __init__(self):
+ self.values = []
- def addValue(self, value):
- self.values.append(value)
+ def addValue(self, value):
+ self.values.append(value)
- def getValues(self, ):
- time.sleep(1)
- return self.values
+ def getValues(self, ):
+ time.sleep(1)
+ return self.values
processor = Aggr.Processor(AggrHandler())
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
diff --git a/contrib/fb303/README b/contrib/fb303/README.md
index 8ade560c9..8ade560c9 100644
--- a/contrib/fb303/README
+++ b/contrib/fb303/README.md
diff --git a/contrib/fb303/TClientInfo.cpp b/contrib/fb303/TClientInfo.cpp
index 5959fb1fa..1fc661251 100644
--- a/contrib/fb303/TClientInfo.cpp
+++ b/contrib/fb303/TClientInfo.cpp
@@ -154,9 +154,8 @@ void TClientInfoServerHandler::getStatsStrings(vector<string>& result) {
}
timespec start;
- double secs = 0.0;
info->getTime(&start);
- secs = (double)(now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec)*0.000000001;
+ double secs = (double)(now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec)*0.000000001;
char buf[256];
snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs,
diff --git a/contrib/fb303/TClientInfo.h b/contrib/fb303/TClientInfo.h
index d0a977025..6668c1921 100644
--- a/contrib/fb303/TClientInfo.h
+++ b/contrib/fb303/TClientInfo.h
@@ -192,7 +192,7 @@ class TClientInfoConnection {
/**
* Return as string the thrift call either currently being processed or
- * most recently processed if the connection is still open for additonal
+ * most recently processed if the connection is still open for additional
* calls. Returns NULL if a call hasn't been made yet or processing
* has ended.
*/
diff --git a/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4 b/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 000000000..a4c9189c9
--- /dev/null
+++ b/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,134 @@
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+# Check for baseline language coverage in the compiler for the C++11
+# standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+# The first argument, if specified, indicates whether you insist on an
+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+# -std=c++11). If neither is specified, you get whatever works, with
+# preference for an extended mode.
+#
+# The second argument, if specified 'mandatory' or if left unspecified,
+# indicates that baseline C++11 support is required and that the macro
+# should error out if no mode with that support is found. If specified
+# 'optional', then configuration proceeds regardless, after defining
+# HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 3
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ typedef check<check<bool>> right_angle_brackets;
+
+ int a;
+ decltype(a) b;
+
+ typedef check<int> check_type;
+ check_type c;
+ check_type&& cr = static_cast<check_type&&>(c);
+
+ auto d = a;
+])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+ m4_if([$1], [], [],
+ [$1], [ext], [],
+ [$1], [noext], [],
+ [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+ [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+ [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ AC_LANG_PUSH([C++])dnl
+ ac_success=no
+ AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+ ax_cv_cxx_compile_cxx11,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [ax_cv_cxx_compile_cxx11=yes],
+ [ax_cv_cxx_compile_cxx11=no])])
+ if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+ ac_success=yes
+ fi
+
+ m4_if([$1], [noext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=gnu++11; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+
+ m4_if([$1], [ext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=c++11; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+ AC_LANG_POP([C++])
+ if test x$ax_cxx_compile_cxx11_required = xtrue; then
+ if test x$ac_success = xno; then
+ AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+ fi
+ else
+ if test x$ac_success = xno; then
+ HAVE_CXX11=0
+ AC_MSG_NOTICE([No compiler with C++11 support was found])
+ else
+ HAVE_CXX11=1
+ AC_DEFINE(HAVE_CXX11,1,
+ [define if the compiler supports basic C++11 syntax])
+ fi
+
+ AC_SUBST(HAVE_CXX11)
+ fi
+])
+
diff --git a/contrib/fb303/aclocal/ax_javac_and_java.m4 b/contrib/fb303/aclocal/ax_javac_and_java.m4
index fdb4bf005..581b45066 100644
--- a/contrib/fb303/aclocal/ax_javac_and_java.m4
+++ b/contrib/fb303/aclocal/ax_javac_and_java.m4
@@ -7,7 +7,7 @@ dnl If "JAVA" is defined in the environment, that will be the only
dnl java command tested. Otherwise, a hard-coded list will be used.
dnl Similarly for "JAVAC".
dnl
-dnl AX_JAVAC_AND_JAVA does not currenly support testing for a particular
+dnl AX_JAVAC_AND_JAVA does not currently support testing for a particular
dnl Java version, testing for only one of "java" and "javac", or
dnl compiling or running user-provided Java code.
dnl
diff --git a/contrib/fb303/configure.ac b/contrib/fb303/configure.ac
index 5b99f2a09..73b35ba07 100644
--- a/contrib/fb303/configure.ac
+++ b/contrib/fb303/configure.ac
@@ -71,6 +71,7 @@ FB_ENABLE_DEFAULT_STATIC
# Example: sets $(thrift_home) variable with default path set to /usr/local.
FB_WITH_PATH([thrift_home], [thriftpath], [/usr/local])
+AX_CXX_COMPILE_STDCXX_11([noext])
AX_THRIFT_LIB(cpp, [C++], yes)
have_cpp=no
if test "$with_cpp" = "yes"; then
diff --git a/contrib/fb303/cpp/FacebookBase.cpp b/contrib/fb303/cpp/FacebookBase.cpp
index 800334068..3c569759c 100644
--- a/contrib/fb303/cpp/FacebookBase.cpp
+++ b/contrib/fb303/cpp/FacebookBase.cpp
@@ -98,7 +98,7 @@ void FacebookBase::getCounters(std::map<std::string, int64_t>& _return) {
// want our read/write structure to go over the wire
counters_.acquireRead();
for(ReadWriteCounterMap::iterator it = counters_.begin();
- it != counters_.end(); it++)
+ it != counters_.end(); ++it)
{
_return[it->first] = it->second.value;
}
diff --git a/contrib/fb303/cpp/FacebookBase.h b/contrib/fb303/cpp/FacebookBase.h
index 2159c95fd..daa524644 100644
--- a/contrib/fb303/cpp/FacebookBase.h
+++ b/contrib/fb303/cpp/FacebookBase.h
@@ -22,6 +22,7 @@
#include "FacebookService.h"
+#include <boost/shared_ptr.hpp>
#include <thrift/server/TServer.h>
#include <thrift/concurrency/Mutex.h>
diff --git a/contrib/fb303/cpp/ServiceTracker.cpp b/contrib/fb303/cpp/ServiceTracker.cpp
index 2914ff65a..7a61b21a9 100644
--- a/contrib/fb303/cpp/ServiceTracker.cpp
+++ b/contrib/fb303/cpp/ServiceTracker.cpp
@@ -251,7 +251,7 @@ ServiceTracker::reportCheckpoint()
uint64_t count;
for (iter = checkpointServiceDuration_.begin();
iter != checkpointServiceDuration_.end();
- iter++) {
+ ++iter) {
count = iter->second.first;
handler_->setCounter(string("checkpoint_count_") + iter->first, count);
if (count == 0) {
diff --git a/contrib/fb303/if/fb303.thrift b/contrib/fb303/if/fb303.thrift
index 66c831527..89bd6eb7b 100644
--- a/contrib/fb303/if/fb303.thrift
+++ b/contrib/fb303/if/fb303.thrift
@@ -24,6 +24,7 @@
namespace java com.facebook.fb303
namespace cpp facebook.fb303
namespace perl Facebook.FB303
+namespace netcore Facebook.FB303.Test
/**
* Common status reporting mechanism across all services
diff --git a/contrib/fb303/java/build.properties b/contrib/fb303/java/build.properties
new file mode 100644
index 000000000..84636683c
--- /dev/null
+++ b/contrib/fb303/java/build.properties
@@ -0,0 +1,5 @@
+# Maven Ant tasks Jar details
+mvn.ant.task.version=2.1.3
+mvn.repo=http://repo1.maven.org/maven2
+mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version}
+mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar
diff --git a/contrib/fb303/java/build.xml b/contrib/fb303/java/build.xml
index 8f2fa51c7..7a1b8f105 100755
--- a/contrib/fb303/java/build.xml
+++ b/contrib/fb303/java/build.xml
@@ -7,9 +7,9 @@
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
@@ -26,20 +26,20 @@
<property name="interface.dir" value="${basedir}/../if"/>
<property name="thrift.java.dir" location="${thrift.root}/lib/java"/>
<property name="build.tools.dir" location="${thrift.java.dir}/build/tools/"/>
- <property name="thrift_compiler" value="${thrift.root}/compiler/cpp/thrift"/>
+ <property name="thrift_compiler" value="${thrift.root}/compiler/cpp/thrift"/>
+ <property file="${basedir}/build.properties"/>
<!-- inherit from the java build file for version and other properties -->
- <property file="${thrift.java.dir}/build.properties" />
+ <property file="${thrift.java.dir}/gradle.properties" />
<property environment="env"/>
<condition property="version" value="${thrift.version}">
<isset property="release"/>
</condition>
- <property name="version" value="${thrift.version}-snapshot"/>
+ <property name="version" value="${thrift.version}-SNAPSHOT"/>
<property name="fb303.final.name" value="${fb303.artifactid}-${version}"/>
- <property name="thrift.java.libthrift" value="${thrift.java.dir}/build/libthrift-${version}.jar"/>
<property name="src" value="${basedir}/src"/>
<property name="gen" value="${basedir}/gen-java"/>
@@ -74,8 +74,12 @@
<echo message="Building ${fb303.final.name}.jar"/>
<javac destdir="${build.classes.dir}" debug="on">
<classpath>
- <pathelement location="${thrift.java.libthrift}"/>
- <fileset dir="${thrift.root}/lib/java/build/lib">
+ <fileset dir="${thrift.java.dir}/build/libs">
+ <include name="libthrift*.jar" />
+ <exclude name="libthrift*javadoc.jar" />
+ <exclude name="libthrift*sources.jar" />
+ </fileset>
+ <fileset dir="${thrift.java.dir}/build/deps">
<include name="*.jar"/>
</fileset>
</classpath>
@@ -120,21 +124,21 @@
<artifact:remoteRepository id="apache" url="${apache.repo}"/>
<!-- Pom file information -->
- <artifact:pom id="pom"
- groupId="${thrift.groupid}"
+ <artifact:pom id="pom"
+ groupId="${thrift.groupid}"
artifactId="${fb303.artifactid}"
- version="${version}"
+ version="${version}"
url="http://thrift.apache.org"
name="Apache Thrift"
description="Thrift is a software framework for scalable cross-language services development."
- packaging="pom"
+ packaging="jar"
>
<remoteRepository refid="central"/>
<remoteRepository refid="apache"/>
<license name="The Apache Software License, Version 2.0" url="${license}"/>
- <scm connection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
- developerConnection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
- url="https://git-wip-us.apache.org/repos/asf?p=thrift.git"
+ <scm connection="scm:git:https://github.com/apache/thrift.git"
+ developerConnection="scm:git:https://github.com/apache/thrift.git"
+ url="https://github.com/apache/thrift"
/>
<!-- Thrift Developers -->
<developer id="mcslee" name="Mark Slee"/>
diff --git a/contrib/fb303/py/fb303/FacebookBase.py b/contrib/fb303/py/fb303/FacebookBase.py
index 685ff20f3..07db10cd3 100644
--- a/contrib/fb303/py/fb303/FacebookBase.py
+++ b/contrib/fb303/py/fb303/FacebookBase.py
@@ -24,59 +24,60 @@ import FacebookService
import thrift.reflection.limited
from ttypes import fb_status
+
class FacebookBase(FacebookService.Iface):
- def __init__(self, name):
- self.name = name
- self.alive = int(time.time())
- self.counters = {}
+ def __init__(self, name):
+ self.name = name
+ self.alive = int(time.time())
+ self.counters = {}
- def getName(self, ):
- return self.name
+ def getName(self, ):
+ return self.name
- def getVersion(self, ):
- return ''
+ def getVersion(self, ):
+ return ''
- def getStatus(self, ):
- return fb_status.ALIVE
+ def getStatus(self, ):
+ return fb_status.ALIVE
- def getCounters(self):
- return self.counters
+ def getCounters(self):
+ return self.counters
- def resetCounter(self, key):
- self.counters[key] = 0
+ def resetCounter(self, key):
+ self.counters[key] = 0
- def getCounter(self, key):
- if self.counters.has_key(key):
- return self.counters[key]
- return 0
+ def getCounter(self, key):
+ if self.counters.has_key(key):
+ return self.counters[key]
+ return 0
- def incrementCounter(self, key):
- self.counters[key] = self.getCounter(key) + 1
+ def incrementCounter(self, key):
+ self.counters[key] = self.getCounter(key) + 1
- def setOption(self, key, value):
- pass
+ def setOption(self, key, value):
+ pass
- def getOption(self, key):
- return ""
+ def getOption(self, key):
+ return ""
- def getOptions(self):
- return {}
+ def getOptions(self):
+ return {}
- def getOptions(self):
- return {}
+ def getOptions(self):
+ return {}
- def aliveSince(self):
- return self.alive
+ def aliveSince(self):
+ return self.alive
- def getCpuProfile(self, duration):
- return ""
+ def getCpuProfile(self, duration):
+ return ""
- def getLimitedReflection(self):
- return thrift.reflection.limited.Service()
+ def getLimitedReflection(self):
+ return thrift.reflection.limited.Service()
- def reinitialize(self):
- pass
+ def reinitialize(self):
+ pass
- def shutdown(self):
- pass
+ def shutdown(self):
+ pass
diff --git a/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py b/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py
index 4f8ce9933..5c8f409c1 100644
--- a/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py
+++ b/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
@@ -19,7 +19,9 @@
# under the License.
#
-import sys, os
+from __future__ import print_function
+import sys
+import os
from optparse import OptionParser
from thrift.Thrift import *
@@ -31,11 +33,12 @@ from thrift.protocol import TBinaryProtocol
from fb303 import *
from fb303.ttypes import *
+
def service_ctrl(
- command,
- port,
- trans_factory = None,
- prot_factory = None):
+ command,
+ port,
+ trans_factory=None,
+ prot_factory=None):
"""
service_ctrl is a generic function to execute standard fb303 functions
@@ -55,66 +58,59 @@ def service_ctrl(
msg = fb_status_string(status)
if (len(status_details)):
msg += " - %s" % status_details
- print msg
-
- if (status == fb_status.ALIVE):
- return 2
- else:
- return 3
+ print(msg)
+ return 2 if status == fb_status.ALIVE else 3
except:
- print "Failed to get status"
+ print("Failed to get status")
return 3
# scalar commands
- if command in ["version","alive","name"]:
+ if command in ["version", "alive", "name"]:
try:
- result = fb303_wrapper(command, port, trans_factory, prot_factory)
- print result
+ result = fb303_wrapper(command, port, trans_factory, prot_factory)
+ print(result)
return 0
except:
- print "failed to get ",command
+ print("failed to get ", command)
return 3
# counters
if command in ["counters"]:
try:
- counters = fb303_wrapper('counters', port, trans_factory, prot_factory)
+ counters = fb303_wrapper('counters', port, trans_factory, prot_factory)
for counter in counters:
- print "%s: %d" % (counter, counters[counter])
+ print("%s: %d" % (counter.encode('utf-8'), counters[counter]))
return 0
except:
- print "failed to get counters"
+ print("failed to get counters")
return 3
-
# Only root should be able to run the following commands
if os.getuid() == 0:
# async commands
- if command in ["stop","reload"] :
+ if command in ["stop", "reload"]:
try:
fb303_wrapper(command, port, trans_factory, prot_factory)
return 0
except:
- print "failed to tell the service to ", command
+ print("failed to tell the service to ", command)
return 3
else:
- if command in ["stop","reload"]:
- print "root privileges are required to stop or reload the service."
+ if command in ["stop", "reload"]:
+ print("root privileges are required to stop or reload the service.")
return 4
- print "The following commands are available:"
- for command in ["counters","name","version","alive","status"]:
- print "\t%s" % command
- print "The following commands are available for users with root privileges:"
- for command in ["stop","reload"]:
- print "\t%s" % command
-
-
+ print("The following commands are available:")
+ for command in ["counters", "name", "version", "alive", "status"]:
+ print("\t%s" % command)
+ print("The following commands are available for users with root privileges:")
+ for command in ["stop", "reload"]:
+ print("\t%s" % command)
- return 0;
+ return 0
-def fb303_wrapper(command, port, trans_factory = None, prot_factory = None):
+def fb303_wrapper(command, port, trans_factory=None, prot_factory=None):
sock = TSocket.TSocket('localhost', port)
# use input transport factory if provided
@@ -179,11 +175,11 @@ def main():
# parse command line options
parser = OptionParser()
- commands=["stop","counters","status","reload","version","name","alive"]
+ commands = ["stop", "counters", "status", "reload", "version", "name", "alive"]
parser.add_option("-c", "--command", dest="command", help="execute this API",
choices=commands, default="status")
- parser.add_option("-p","--port",dest="port",help="the service's port",
+ parser.add_option("-p", "--port", dest="port", help="the service's port",
default=9082)
(options, args) = parser.parse_args()
diff --git a/contrib/fb303/py/setup.py b/contrib/fb303/py/setup.py
index 6710c8f61..d27c2962f 100644
--- a/contrib/fb303/py/setup.py
+++ b/contrib/fb303/py/setup.py
@@ -24,26 +24,25 @@ try:
from setuptools import setup, Extension
except:
from distutils.core import setup, Extension, Command
-
-setup(name = 'thrift_fb303',
- version = '1.0.0-dev',
- description = 'Python bindings for the Apache Thrift FB303',
- author = ['Thrift Developers'],
- author_email = ['dev@thrift.apache.org'],
- url = 'http://thrift.apache.org',
- license = 'Apache License 2.0',
- packages = [
- 'fb303',
- 'fb303_scripts',
- ],
- classifiers = [
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Console',
- 'Intended Audience :: Developers',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Topic :: Software Development :: Libraries',
- 'Topic :: System :: Networking'
- ],
-)
+setup(name='thrift_fb303',
+ version='1.0.0',
+ description='Python bindings for the Apache Thrift FB303',
+ author=['Apache Thrift Developers'],
+ author_email=['dev@thrift.apache.org'],
+ url='http://thrift.apache.org',
+ license='Apache License 2.0',
+ packages=[
+ 'fb303',
+ 'fb303_scripts',
+ ],
+ classifiers=[
+ 'Development Status :: 7 - Inactive',
+ 'Environment :: Console',
+ 'Intended Audience :: Developers',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Topic :: Software Development :: Libraries',
+ 'Topic :: System :: Networking'
+ ],
+ )
diff --git a/contrib/mingw-cross-compile.sh b/contrib/mingw-cross-compile.sh
index 894ae5fe4..7ed5d4773 100755
--- a/contrib/mingw-cross-compile.sh
+++ b/contrib/mingw-cross-compile.sh
@@ -2,21 +2,10 @@
set -e
./configure \
- --without-cpp \
- --without-c_glib \
- --without-java \
- --without-csharp \
- --without-python \
- --without-ruby \
- --without-haskell \
- --without-perl \
- --without-php \
- --without-erlang \
- --without-go \
- --without-d \
+ --disable-libs \
--build=i686-pc-linux-gnu \
--host=i586-mingw32msvc \
- CPPFLAGS='-DMINGW'
+ CC=i586-mingw32msvc-gcc CXX=i586-mingw32msvc-g++
make
diff --git a/contrib/parse_profiling.py b/contrib/parse_profiling.py
index 52d221176..0be5f29ed 100755
--- a/contrib/parse_profiling.py
+++ b/contrib/parse_profiling.py
@@ -42,10 +42,12 @@ class AddressInfo(object):
self.address = address
self.sourceFile = None
self.sourceLine = None
- self.funtion = None
+ self.function = None
g_addrs_by_filename = {}
+
+
def get_address(filename, address):
"""
Retrieve an AddressInfo object for the specified object file and address.
@@ -103,12 +105,12 @@ def translate_file_addresses(filename, addresses, options):
idx = file_and_line.rfind(':')
if idx < 0:
msg = 'expected file and line number from addr2line; got %r' % \
- (file_and_line,)
+ (file_and_line,)
msg += '\nfile=%r, address=%r' % (filename, address.address)
raise Exception(msg)
address.sourceFile = file_and_line[:idx]
- address.sourceLine = file_and_line[idx+1:]
+ address.sourceLine = file_and_line[idx + 1:]
(remaining_out, cmd_err) = proc.communicate()
retcode = proc.wait()
@@ -180,7 +182,7 @@ def process_file(in_file, out_file, options):
virt_call_regex = re.compile(r'^\s*T_VIRTUAL_CALL: (\d+) calls on (.*):$')
gen_prot_regex = re.compile(
- r'^\s*T_GENERIC_PROTOCOL: (\d+) calls to (.*) with a (.*):$')
+ r'^\s*T_GENERIC_PROTOCOL: (\d+) calls to (.*) with a (.*):$')
bt_regex = re.compile(r'^\s*#(\d+)\s*(.*) \[(0x[0-9A-Za-z]+)\]$')
# Parse all of the input, and store it as Entry objects
@@ -209,7 +211,7 @@ def process_file(in_file, out_file, options):
# "_Z" to the type name to make it look like an external name.
type_name = '_Z' + type_name
header = 'T_VIRTUAL_CALL: %d calls on "%s"' % \
- (num_calls, type_name)
+ (num_calls, type_name)
if current_entry is not None:
entries.append(current_entry)
current_entry = Entry(header)
@@ -224,7 +226,7 @@ def process_file(in_file, out_file, options):
type_name1 = '_Z' + type_name1
type_name2 = '_Z' + type_name2
header = 'T_GENERIC_PROTOCOL: %d calls to "%s" with a "%s"' % \
- (num_calls, type_name1, type_name2)
+ (num_calls, type_name1, type_name2)
if current_entry is not None:
entries.append(current_entry)
current_entry = Entry(header)
diff --git a/contrib/thrift-maven-plugin/pom.xml b/contrib/thrift-maven-plugin/pom.xml
new file mode 100644
index 000000000..1d66bc619
--- /dev/null
+++ b/contrib/thrift-maven-plugin/pom.xml
@@ -0,0 +1,92 @@
+<?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
+ 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>
+ <groupId>org.apache.thrift</groupId>
+ <artifactId>thrift-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>thrift-maven-plugin</name>
+ <version>1.0.0</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.14.1</version>
+ <configuration>
+ <systemPropertyVariables>
+ <thriftExecutable>${thrift.compiler}</thriftExecutable>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>3.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>14.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>3.0.14</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <properties>
+ <thrift.root>${basedir}/../..</thrift.root>
+ <thrift.compiler>${thrift.root}/compiler/cpp/thrift</thrift.compiler>
+ <thrift.test.home>${thrift.root}/test</thrift.test.home>
+ </properties>
+</project>
diff --git a/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/AbstractThriftMojo.java b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/AbstractThriftMojo.java
new file mode 100644
index 000000000..869be95e4
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/AbstractThriftMojo.java
@@ -0,0 +1,380 @@
+/*
+ * 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.thrift.maven;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.io.RawInputStreamFacade;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Sets.newHashSet;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static java.util.Collections.list;
+import static org.codehaus.plexus.util.FileUtils.cleanDirectory;
+import static org.codehaus.plexus.util.FileUtils.copyStreamToFile;
+import static org.codehaus.plexus.util.FileUtils.getFiles;
+
+/**
+ * Abstract Mojo implementation.
+ * <p/>
+ * This class is extended by {@link org.apache.thrift.maven.ThriftCompileMojo} and
+ * {@link org.apache.thrift.maven.ThriftTestCompileMojo} in order to override the specific configuration for
+ * compiling the main or test classes respectively.
+ */
+abstract class AbstractThriftMojo extends AbstractMojo {
+
+ private static final String THRIFT_FILE_SUFFIX = ".thrift";
+
+ private static final String DEFAULT_INCLUDES = "**/*" + THRIFT_FILE_SUFFIX;
+
+ /**
+ * The current Maven project.
+ *
+ * @parameter default-value="${project}"
+ * @readonly
+ * @required
+ */
+ protected MavenProject project;
+
+ /**
+ * A helper used to add resources to the project.
+ *
+ * @component
+ * @required
+ */
+ protected MavenProjectHelper projectHelper;
+
+ /**
+ * This is the path to the {@code thrift} executable. By default it will search the {@code $PATH}.
+ *
+ * @parameter default-value="thrift"
+ * @required
+ */
+ private String thriftExecutable;
+
+ /**
+ * This string is passed to the {@code --gen} option of the {@code thrift} parameter. By default
+ * it will generate Java output. The main reason for this option is to be able to add options
+ * to the Java generator - if you generate something else, you're on your own.
+ *
+ * @parameter default-value="java"
+ */
+ private String generator;
+
+ /**
+ * @parameter
+ */
+ private File[] additionalThriftPathElements = new File[]{};
+
+ /**
+ * Since {@code thrift} cannot access jars, thrift files in dependencies are extracted to this location
+ * and deleted on exit. This directory is always cleaned during execution.
+ *
+ * @parameter default-value="${project.build.directory}/thrift-dependencies"
+ * @required
+ */
+ private File temporaryThriftFileDirectory;
+
+ /**
+ * This is the path to the local maven {@code repository}.
+ *
+ * @parameter default-value="${localRepository}"
+ * @required
+ */
+ protected ArtifactRepository localRepository;
+
+ /**
+ * Set this to {@code false} to disable hashing of dependent jar paths.
+ * <p/>
+ * This plugin expands jars on the classpath looking for embedded .thrift files.
+ * Normally these paths are hashed (MD5) to avoid issues with long file names on windows.
+ * However if this property is set to {@code false} longer paths will be used.
+ *
+ * @parameter default-value="true"
+ * @required
+ */
+ protected boolean hashDependentPaths;
+
+ /**
+ * @parameter
+ */
+ private Set<String> includes = ImmutableSet.of(DEFAULT_INCLUDES);
+
+ /**
+ * @parameter
+ */
+ private Set<String> excludes = ImmutableSet.of();
+
+ /**
+ * @parameter
+ */
+ private long staleMillis = 0;
+
+ /**
+ * @parameter
+ */
+ private boolean checkStaleness = false;
+
+ /**
+ * Executes the mojo.
+ */
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ checkParameters();
+ final File thriftSourceRoot = getThriftSourceRoot();
+ if (thriftSourceRoot.exists()) {
+ try {
+ ImmutableSet<File> thriftFiles = findThriftFilesInDirectory(thriftSourceRoot);
+ final File outputDirectory = getOutputDirectory();
+ ImmutableSet<File> outputFiles = findGeneratedFilesInDirectory(getOutputDirectory());
+
+ if (thriftFiles.isEmpty()) {
+ getLog().info("No thrift files to compile.");
+ } else if (checkStaleness && ((lastModified(thriftFiles) + staleMillis) < lastModified(outputFiles))) {
+ getLog().info("Skipping compilation because target directory newer than sources.");
+ attachFiles();
+ } else {
+ ImmutableSet<File> derivedThriftPathElements =
+ makeThriftPathFromJars(temporaryThriftFileDirectory, getDependencyArtifactFiles());
+ outputDirectory.mkdirs();
+
+ // Quick fix to fix issues with two mvn installs in a row (ie no clean)
+ // cleanDirectory(outputDirectory);
+
+ Thrift thrift = new Thrift.Builder(thriftExecutable, outputDirectory)
+ .setGenerator(generator)
+ .addThriftPathElement(thriftSourceRoot)
+ .addThriftPathElements(derivedThriftPathElements)
+ .addThriftPathElements(asList(additionalThriftPathElements))
+ .addThriftFiles(thriftFiles)
+ .build();
+ final int exitStatus = thrift.compile();
+ if (exitStatus != 0) {
+ getLog().error("thrift failed output: " + thrift.getOutput());
+ getLog().error("thrift failed error: " + thrift.getError());
+ throw new MojoFailureException(
+ "thrift did not exit cleanly. Review output for more information.");
+ }
+ attachFiles();
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException("An IO error occurred", e);
+ } catch (IllegalArgumentException e) {
+ throw new MojoFailureException("thrift failed to execute because: " + e.getMessage(), e);
+ } catch (CommandLineException e) {
+ throw new MojoExecutionException("An error occurred while invoking thrift.", e);
+ }
+ } else {
+ getLog().info(format("%s does not exist. Review the configuration or consider disabling the plugin.",
+ thriftSourceRoot));
+ }
+ }
+
+ ImmutableSet<File> findGeneratedFilesInDirectory(File directory) throws IOException {
+ if (directory == null || !directory.isDirectory())
+ return ImmutableSet.of();
+
+ List<File> javaFilesInDirectory = getFiles(directory, "**/*.java", null);
+ return ImmutableSet.copyOf(javaFilesInDirectory);
+ }
+
+ private long lastModified(ImmutableSet<File> files) {
+ long result = 0;
+ for (File file : files) {
+ if (file.lastModified() > result)
+ result = file.lastModified();
+ }
+ return result;
+ }
+
+ private void checkParameters() {
+ checkNotNull(project, "project");
+ checkNotNull(projectHelper, "projectHelper");
+ checkNotNull(thriftExecutable, "thriftExecutable");
+ checkNotNull(generator, "generator");
+ final File thriftSourceRoot = getThriftSourceRoot();
+ checkNotNull(thriftSourceRoot);
+ checkArgument(!thriftSourceRoot.isFile(), "thriftSourceRoot is a file, not a directory");
+ checkNotNull(temporaryThriftFileDirectory, "temporaryThriftFileDirectory");
+ checkState(!temporaryThriftFileDirectory.isFile(), "temporaryThriftFileDirectory is a file, not a directory");
+ final File outputDirectory = getOutputDirectory();
+ checkNotNull(outputDirectory);
+ checkState(!outputDirectory.isFile(), "the outputDirectory is a file, not a directory");
+ }
+
+ protected abstract File getThriftSourceRoot();
+
+ protected abstract List<Artifact> getDependencyArtifacts();
+
+ protected abstract File getOutputDirectory();
+
+ protected abstract void attachFiles();
+
+ /**
+ * Gets the {@link File} for each dependency artifact.
+ *
+ * @return A set of all dependency artifacts.
+ */
+ private ImmutableSet<File> getDependencyArtifactFiles() {
+ Set<File> dependencyArtifactFiles = newHashSet();
+ for (Artifact artifact : getDependencyArtifacts()) {
+ dependencyArtifactFiles.add(artifact.getFile());
+ }
+ return ImmutableSet.copyOf(dependencyArtifactFiles);
+ }
+
+ /**
+ * @throws IOException
+ */
+ ImmutableSet<File> makeThriftPathFromJars(File temporaryThriftFileDirectory, Iterable<File> classpathElementFiles)
+ throws IOException, MojoExecutionException {
+ checkNotNull(classpathElementFiles, "classpathElementFiles");
+ // clean the temporary directory to ensure that stale files aren't used
+ if (temporaryThriftFileDirectory.exists()) {
+ cleanDirectory(temporaryThriftFileDirectory);
+ }
+
+ Set<File> thriftDirectories = newHashSet();
+
+ for (File classpathElementFile : classpathElementFiles) {
+ // for some reason under IAM, we receive poms as dependent files
+ // I am excluding .xml rather than including .jar as there may be other extensions in use (sar, har, zip)
+ if (classpathElementFile.isFile() && classpathElementFile.canRead() &&
+ !classpathElementFile.getName().endsWith(".xml")) {
+
+ // create the jar file. the constructor validates.
+ JarFile classpathJar;
+ try {
+ classpathJar = new JarFile(classpathElementFile);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(format(
+ "%s was not a readable artifact", classpathElementFile));
+ }
+
+ /**
+ * Copy each .thrift file found in the JAR into a temporary directory, preserving the
+ * directory path it had relative to its containing JAR. Add the resulting root directory
+ * (unique for each JAR processed) to the set of thrift include directories to use when
+ * compiling.
+ */
+ for (JarEntry jarEntry : list(classpathJar.entries())) {
+ final String jarEntryName = jarEntry.getName();
+ if (jarEntry.getName().endsWith(THRIFT_FILE_SUFFIX)) {
+ final String truncatedJarPath = truncatePath(classpathJar.getName());
+ final File thriftRootDirectory = new File(temporaryThriftFileDirectory, truncatedJarPath);
+ final File uncompressedCopy =
+ new File(thriftRootDirectory, jarEntryName);
+ uncompressedCopy.getParentFile().mkdirs();
+ copyStreamToFile(new RawInputStreamFacade(classpathJar
+ .getInputStream(jarEntry)), uncompressedCopy);
+ thriftDirectories.add(thriftRootDirectory);
+ }
+ }
+
+ } else if (classpathElementFile.isDirectory()) {
+ File[] thriftFiles = classpathElementFile.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(THRIFT_FILE_SUFFIX);
+ }
+ });
+
+ if (thriftFiles.length > 0) {
+ thriftDirectories.add(classpathElementFile);
+ }
+ }
+ }
+
+ return ImmutableSet.copyOf(thriftDirectories);
+ }
+
+ ImmutableSet<File> findThriftFilesInDirectory(File directory) throws IOException {
+ checkNotNull(directory);
+ checkArgument(directory.isDirectory(), "%s is not a directory", directory);
+ List<File> thriftFilesInDirectory = getFiles(directory,
+ Joiner.on(",").join(includes),
+ Joiner.on(",").join(excludes));
+ return ImmutableSet.copyOf(thriftFilesInDirectory);
+ }
+
+ /**
+ * Truncates the path of jar files so that they are relative to the local repository.
+ *
+ * @param jarPath the full path of a jar file.
+ * @return the truncated path relative to the local repository or root of the drive.
+ */
+ String truncatePath(final String jarPath) throws MojoExecutionException {
+
+ if (hashDependentPaths) {
+ try {
+ return toHexString(MessageDigest.getInstance("MD5").digest(jarPath.getBytes()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new MojoExecutionException("Failed to expand dependent jar", e);
+ }
+ }
+
+ String repository = localRepository.getBasedir().replace('\\', '/');
+ if (!repository.endsWith("/")) {
+ repository += "/";
+ }
+
+ String path = jarPath.replace('\\', '/');
+ int repositoryIndex = path.indexOf(repository);
+ if (repositoryIndex != -1) {
+ path = path.substring(repositoryIndex + repository.length());
+ }
+
+ // By now the path should be good, but do a final check to fix windows machines.
+ int colonIndex = path.indexOf(':');
+ if (colonIndex != -1) {
+ // 2 = :\ in C:\
+ path = path.substring(colonIndex + 2);
+ }
+
+ return path;
+ }
+
+ private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
+
+ public static String toHexString(byte[] byteArray) {
+ final StringBuilder hexString = new StringBuilder(2 * byteArray.length);
+ for (final byte b : byteArray) {
+ hexString.append(HEX_CHARS[(b & 0xF0) >> 4]).append(HEX_CHARS[b & 0x0F]);
+ }
+ return hexString.toString();
+ }
+}
diff --git a/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/Thrift.java b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/Thrift.java
new file mode 100644
index 000000000..6eea95448
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/Thrift.java
@@ -0,0 +1,262 @@
+/*
+ * 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.thrift.maven;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Lists.newLinkedList;
+import static com.google.common.collect.Sets.newHashSet;
+
+/**
+ * This class represents an invokable configuration of the {@code thrift}
+ * compiler. The actual executable is invoked using the plexus
+ * {@link Commandline}.
+ * <p/>
+ * This class currently only supports generating java source files.
+ */
+final class Thrift {
+
+ final static String GENERATED_JAVA = "gen-java";
+
+ private final String executable;
+ private final String generator;
+ private final ImmutableSet<File> thriftPathElements;
+ private final ImmutableSet<File> thriftFiles;
+ private final File javaOutputDirectory;
+ private final CommandLineUtils.StringStreamConsumer output;
+ private final CommandLineUtils.StringStreamConsumer error;
+
+ /**
+ * Constructs a new instance. This should only be used by the {@link Builder}.
+ *
+ * @param executable The path to the {@code thrift} executable.
+ * @param generator The value for the {@code --gen} option.
+ * @param thriftPath The directories in which to search for imports.
+ * @param thriftFiles The thrift source files to compile.
+ * @param javaOutputDirectory The directory into which the java source files
+ * will be generated.
+ */
+ private Thrift(String executable, String generator, ImmutableSet<File> thriftPath,
+ ImmutableSet<File> thriftFiles, File javaOutputDirectory) {
+ this.executable = checkNotNull(executable, "executable");
+ this.generator = checkNotNull(generator, "generator");
+ this.thriftPathElements = checkNotNull(thriftPath, "thriftPath");
+ this.thriftFiles = checkNotNull(thriftFiles, "thriftFiles");
+ this.javaOutputDirectory = checkNotNull(javaOutputDirectory, "javaOutputDirectory");
+ this.error = new CommandLineUtils.StringStreamConsumer();
+ this.output = new CommandLineUtils.StringStreamConsumer();
+ }
+
+ /**
+ * Invokes the {@code thrift} compiler using the configuration specified at
+ * construction.
+ *
+ * @return The exit status of {@code thrift}.
+ * @throws CommandLineException
+ */
+ public int compile() throws CommandLineException {
+
+ for (File thriftFile : thriftFiles) {
+ Commandline cl = new Commandline();
+ cl.setExecutable(executable);
+ cl.addArguments(buildThriftCommand(thriftFile).toArray(new String[]{}));
+ final int result = CommandLineUtils.executeCommandLine(cl, null, output, error);
+
+ if (result != 0) {
+ return result;
+ }
+ }
+
+ // result will always be 0 here.
+ return 0;
+ }
+
+ /**
+ * Creates the command line arguments.
+ * <p/>
+ * This method has been made visible for testing only.
+ *
+ * @param thriftFile
+ * @return A list consisting of the executable followed by any arguments.
+ */
+ ImmutableList<String> buildThriftCommand(final File thriftFile) {
+ final List<String> command = newLinkedList();
+ // add the executable
+ for (File thriftPathElement : thriftPathElements) {
+ command.add("-I");
+ command.add(thriftPathElement.toString());
+ }
+ command.add("-out");
+ command.add(javaOutputDirectory.toString());
+ command.add("--gen");
+ command.add(generator);
+ command.add(thriftFile.toString());
+ return ImmutableList.copyOf(command);
+ }
+
+ /**
+ * @return the output
+ */
+ public String getOutput() {
+ return output.getOutput();
+ }
+
+ /**
+ * @return the error
+ */
+ public String getError() {
+ return error.getOutput();
+ }
+
+ /**
+ * This class builds {@link Thrift} instances.
+ */
+ static final class Builder {
+ private final String executable;
+ private final File javaOutputDirectory;
+ private Set<File> thriftPathElements;
+ private Set<File> thriftFiles;
+ private String generator;
+
+ /**
+ * Constructs a new builder. The two parameters are present as they are
+ * required for all {@link Thrift} instances.
+ *
+ * @param executable The path to the {@code thrift} executable.
+ * @param javaOutputDirectory The directory into which the java source files
+ * will be generated.
+ * @throws NullPointerException If either of the arguments are {@code null}.
+ * @throws IllegalArgumentException If the {@code javaOutputDirectory} is
+ * not a directory.
+ */
+ public Builder(String executable, File javaOutputDirectory) {
+ this.executable = checkNotNull(executable, "executable");
+ this.javaOutputDirectory = checkNotNull(javaOutputDirectory);
+ checkArgument(javaOutputDirectory.isDirectory());
+ this.thriftFiles = newHashSet();
+ this.thriftPathElements = newHashSet();
+ }
+
+ /**
+ * Adds a thrift file to be compiled. Thrift files must be on the thriftpath
+ * and this method will fail if a thrift file is added without first adding a
+ * parent directory to the thriftpath.
+ *
+ * @param thriftFile
+ * @return The builder.
+ * @throws IllegalStateException If a thrift file is added without first
+ * adding a parent directory to the thriftpath.
+ * @throws NullPointerException If {@code thriftFile} is {@code null}.
+ */
+ public Builder addThriftFile(File thriftFile) {
+ checkNotNull(thriftFile);
+ checkArgument(thriftFile.isFile());
+ checkArgument(thriftFile.getName().endsWith(".thrift"));
+ checkThriftFileIsInThriftPath(thriftFile);
+ thriftFiles.add(thriftFile);
+ return this;
+ }
+
+ /**
+ * Adds the option string for the Thrift executable's {@code --gen} parameter.
+ *
+ * @param generator
+ * @return The builder
+ * @throws NullPointerException If {@code generator} is {@code null}.
+ */
+ public Builder setGenerator(String generator) {
+ checkNotNull(generator);
+ this.generator = generator;
+ return this;
+ }
+
+ private void checkThriftFileIsInThriftPath(File thriftFile) {
+ assert thriftFile.isFile();
+ checkState(checkThriftFileIsInThriftPathHelper(thriftFile.getParentFile()));
+ }
+
+ private boolean checkThriftFileIsInThriftPathHelper(File directory) {
+ assert directory.isDirectory();
+ if (thriftPathElements.contains(directory)) {
+ return true;
+ } else {
+ final File parentDirectory = directory.getParentFile();
+ return (parentDirectory == null) ? false
+ : checkThriftFileIsInThriftPathHelper(parentDirectory);
+ }
+ }
+
+ /**
+ * @see #addThriftFile(File)
+ */
+ public Builder addThriftFiles(Iterable<File> thriftFiles) {
+ for (File thriftFile : thriftFiles) {
+ addThriftFile(thriftFile);
+ }
+ return this;
+ }
+
+ /**
+ * Adds the {@code thriftPathElement} to the thriftPath.
+ *
+ * @param thriftPathElement A directory to be searched for imported thrift message
+ * buffer definitions.
+ * @return The builder.
+ * @throws NullPointerException If {@code thriftPathElement} is {@code null}.
+ * @throws IllegalArgumentException If {@code thriftPathElement} is not a
+ * directory.
+ */
+ public Builder addThriftPathElement(File thriftPathElement) {
+ checkNotNull(thriftPathElement);
+ checkArgument(thriftPathElement.isDirectory());
+ thriftPathElements.add(thriftPathElement);
+ return this;
+ }
+
+ /**
+ * @see #addThriftPathElement(File)
+ */
+ public Builder addThriftPathElements(Iterable<File> thriftPathElements) {
+ for (File thriftPathElement : thriftPathElements) {
+ addThriftPathElement(thriftPathElement);
+ }
+ return this;
+ }
+
+ /**
+ * @return A configured {@link Thrift} instance.
+ * @throws IllegalStateException If no thrift files have been added.
+ */
+ public Thrift build() {
+ checkState(!thriftFiles.isEmpty());
+ return new Thrift(executable, generator, ImmutableSet.copyOf(thriftPathElements),
+ ImmutableSet.copyOf(thriftFiles), javaOutputDirectory);
+ }
+ }
+}
diff --git a/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftCompileMojo.java b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftCompileMojo.java
new file mode 100644
index 000000000..b4f75714b
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftCompileMojo.java
@@ -0,0 +1,78 @@
+/*
+ * 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.thrift.maven;
+
+import java.io.File;
+import java.util.List;
+import org.apache.maven.artifact.Artifact;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * This mojo executes the {@code thrift} compiler for generating java sources
+ * from thrift definitions. It also searches dependency artifacts for
+ * thrift files and includes them in the thriftPath so that they can be
+ * referenced. Finally, it adds the thrift files to the project as resources so
+ * that they are included in the final artifact.
+ *
+ * @phase generate-sources
+ * @goal compile
+ * @requiresDependencyResolution compile
+ */
+public final class ThriftCompileMojo extends AbstractThriftMojo {
+
+ /**
+ * The source directories containing the sources to be compiled.
+ *
+ * @parameter default-value="${basedir}/src/main/thrift"
+ * @required
+ */
+ private File thriftSourceRoot;
+
+ /**
+ * This is the directory into which the {@code .java} will be created.
+ *
+ * @parameter default-value="${project.build.directory}/generated-sources/thrift"
+ * @required
+ */
+ private File outputDirectory;
+
+ @Override
+ protected List<Artifact> getDependencyArtifacts() {
+ List<Artifact> compileArtifacts = project.getCompileArtifacts();
+ return compileArtifacts;
+ }
+
+ @Override
+ protected File getOutputDirectory() {
+ return outputDirectory;
+ }
+
+ @Override
+ protected File getThriftSourceRoot() {
+ return thriftSourceRoot;
+ }
+
+ @Override
+ protected void attachFiles() {
+ project.addCompileSourceRoot(outputDirectory.getAbsolutePath());
+ projectHelper.addResource(project, thriftSourceRoot.getAbsolutePath(),
+ ImmutableList.of("**/*.thrift"), null);
+ }
+}
diff --git a/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftTestCompileMojo.java b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftTestCompileMojo.java
new file mode 100644
index 000000000..1b1d99e0d
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/ThriftTestCompileMojo.java
@@ -0,0 +1,93 @@
+/*
+ * 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.thrift.maven;
+
+import java.io.File;
+import java.util.List;
+import org.apache.maven.artifact.Artifact;
+import com.google.common.collect.ImmutableList;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * @phase generate-test-sources
+ * @goal testCompile
+ * @requiresDependencyResolution test
+ */
+public final class ThriftTestCompileMojo extends AbstractThriftMojo {
+
+ /**
+ * The source directories containing the sources to be compiled.
+ *
+ * @parameter default-value="${basedir}/src/test/thrift"
+ * @required
+ */
+ private File thriftTestSourceRoot;
+
+ /**
+ * This is the directory into which the {@code .java} will be created.
+ *
+ * @parameter default-value="${project.build.directory}/generated-test-sources/thrift"
+ * @required
+ */
+ private File outputDirectory;
+
+ @Override
+ protected void attachFiles() {
+ project.addTestCompileSourceRoot(outputDirectory.getAbsolutePath());
+ projectHelper.addTestResource(project, thriftTestSourceRoot.getAbsolutePath(),
+ ImmutableList.of("**/*.thrift"), null);
+ }
+
+ @Override
+ protected List<Artifact> getDependencyArtifacts() {
+ // TODO(gak): maven-project needs generics
+ @SuppressWarnings("unchecked")
+ List<Artifact> testArtifacts = project.getTestArtifacts();
+ return testArtifacts;
+ }
+
+ @Override
+ protected File getOutputDirectory() {
+ return outputDirectory;
+ }
+
+ @Override
+ protected File getThriftSourceRoot() {
+ return thriftTestSourceRoot;
+ }
+
+ /**
+ * Set the local maven ArtifactRepository. Exposed only to allow testing outside of Maven itself.
+ *
+ * @param localRepository local ArtifactRepository
+ */
+ public void setLocalMavenRepository(final ArtifactRepository localRepository) {
+ this.localRepository = localRepository;
+ }
+
+ /**
+ * Set the option to hash dependent JAR paths. Exposed only to allow testing outside of Maven itself.
+ *
+ * @param hashDependentPaths whether or not to hash paths to dependent JARs
+ */
+ public void setHashDependentPaths(final boolean hashDependentPaths) {
+ this.hashDependentPaths = hashDependentPaths;
+ }
+}
diff --git a/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestAbstractThriftMojo.java b/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestAbstractThriftMojo.java
new file mode 100644
index 000000000..c1176712d
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestAbstractThriftMojo.java
@@ -0,0 +1,102 @@
+/*
+ * 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.thrift.maven;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.io.File;
+import java.util.Set;
+
+import static junit.framework.TestCase.assertEquals;
+
+
+public class TestAbstractThriftMojo {
+
+ private ThriftTestCompileMojo mojo;
+ private File testRootDir;
+ private ArtifactRepository mavenRepository;
+
+
+ @Before
+ public void setUp() throws Exception {
+ final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
+ testRootDir = new File(tmpDir, "thrift-test");
+
+ // the truncatePath method assumes a maven repository, but it only cares about the base dir
+ mavenRepository = Mockito.mock(ArtifactRepository.class);
+ Mockito.when(mavenRepository.getBasedir()).thenReturn("/test/maven/repo/basedir");
+
+ mojo = new ThriftTestCompileMojo();
+ mojo.setLocalMavenRepository(mavenRepository);
+ }
+
+ @Test
+ public void testMakeThriftPathFromJars() throws Throwable {
+ final File temporaryThriftFileDirectory = testRootDir;
+
+ // The SharedIdl.jar file contains the same idl/shared.thrift and idl/tutorial.thrift hierarchy
+ // used by other tests. It's used here to represent a dependency of the project maven is building,
+ // one that is contributing .thrift IDL files as well as any other artifacts.
+ final Iterable<File> classpathElementFiles = Lists.newArrayList(
+ new File("src/test/resources/dependency-jar-test/SharedIdl.jar")
+ );
+
+ final Set<File> thriftDirectories = mojo.makeThriftPathFromJars(temporaryThriftFileDirectory, classpathElementFiles);
+
+ // The results should be a path to a directory named after the JAR itself (assuming no path hashing,
+ // but see below for a separate test of that) representing the root of a hierarchy containing thrift
+ // files, suitable for providing to the thrift compiler as an include directory. In this case, that
+ // means it points to the directory containing the "idl" hierarchy rather than to the idl directory
+ // itself.
+ final Set<File> expected = Sets.newHashSet(
+ new File(testRootDir, "src/test/resources/dependency-jar-test/SharedIdl.jar")
+ );
+
+ assertEquals("makeThriftPathFromJars should return thrift IDL base path from within JAR", expected, thriftDirectories);
+ }
+
+ @Test
+ public void testTruncatePath() throws Throwable {
+ // JAR path is unrelated to maven repo, and should be unchanged
+ assertEquals("/path/to/somejar.jar", mojo.truncatePath("/path/to/somejar.jar"));
+
+ // JAR path is within maven repo, and should be made relative to the repo
+ assertEquals("path/to/somejar.jar", mojo.truncatePath("/test/maven/repo/basedir/path/to/somejar.jar"));
+
+ // JAR path contains forward slashes that should be normalized
+ assertEquals("/path/to/somejar.jar", mojo.truncatePath("\\path\\to\\somejar.jar"));
+ }
+
+ @Test
+ public void testTruncatePathWithDependentPathHashing() throws Throwable {
+ mojo.setHashDependentPaths(true);
+
+ // hashDependentPaths set to true, the JAR path is immediately hashed (MD5) and converted to a hex string
+
+ assertEquals("1c85950987b23493462cf3c261d9510a", mojo.truncatePath("/path/to/somejar.jar"));
+ assertEquals("39fc2b4c34cb6cb0da38bed5d8b5fc67", mojo.truncatePath("/test/maven/repo/basedir/path/to/somejar.jar"));
+ assertEquals("25b6924f5b0e19486d0ff88448e999d5", mojo.truncatePath("\\path\\to\\somejar.jar"));
+ }
+
+}
diff --git a/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestThrift.java b/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestThrift.java
new file mode 100644
index 000000000..7c7891edf
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestThrift.java
@@ -0,0 +1,163 @@
+/*
+ * 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.thrift.maven;
+
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class TestThrift {
+
+ private File testRootDir;
+ private File idlDir;
+ private File genJavaDir;
+ private Thrift.Builder builder;
+
+ @Before
+ public void setup() throws Exception {
+ final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
+ testRootDir = new File(tmpDir, "thrift-test");
+
+ if (testRootDir.exists()) {
+ FileUtils.cleanDirectory(testRootDir);
+ } else {
+ assertTrue("Failed to create output directory for test: " + testRootDir.getPath(), testRootDir.mkdir());
+ }
+
+ File testResourceDir = new File("src/test/resources");
+ assertTrue("Unable to find test resources", testRootDir.exists());
+
+ String thriftExecutable = System.getProperty("thriftExecutable", "thrift");
+ if (!(new File(thriftExecutable).exists())) {
+ thriftExecutable = "thrift";
+ }
+ System.out.println("Thrift compiler: " + thriftExecutable);
+
+ idlDir = new File(testResourceDir, "idl");
+ genJavaDir = new File(testRootDir, Thrift.GENERATED_JAVA);
+ builder = new Thrift.Builder(thriftExecutable, testRootDir);
+ builder
+ .setGenerator("java")
+ .addThriftPathElement(idlDir);
+ }
+
+ @Test
+ public void testThriftCompile() throws Exception {
+ executeThriftCompile();
+ }
+
+ @Test
+ public void testThriftCompileWithGeneratorOption() throws Exception {
+ builder.setGenerator("java:private-members");
+ executeThriftCompile();
+ }
+
+ private void executeThriftCompile() throws CommandLineException {
+ final File thriftFile = new File(idlDir, "shared.thrift");
+
+ builder.addThriftFile(thriftFile);
+
+ final Thrift thrift = builder.build();
+
+ assertTrue("File not found: shared.thrift", thriftFile.exists());
+ assertFalse("gen-java directory should not exist", genJavaDir.exists());
+
+ // execute the compile
+ final int result = thrift.compile();
+ assertEquals(0, result);
+
+ assertFalse("gen-java directory was not removed", genJavaDir.exists());
+ assertTrue("generated java code doesn't exist",
+ new File(testRootDir, "shared/SharedService.java").exists());
+ }
+
+ @Test
+ public void testThriftMultipleFileCompile() throws Exception {
+ final File sharedThrift = new File(idlDir, "shared.thrift");
+ final File tutorialThrift = new File(idlDir, "tutorial.thrift");
+
+ builder.addThriftFile(sharedThrift);
+ builder.addThriftFile(tutorialThrift);
+
+ final Thrift thrift = builder.build();
+
+ assertTrue("File not found: shared.thrift", sharedThrift.exists());
+ assertFalse("gen-java directory should not exist", genJavaDir.exists());
+
+ // execute the compile
+ final int result = thrift.compile();
+ assertEquals(0, result);
+
+ assertFalse("gen-java directory was not removed", genJavaDir.exists());
+ assertTrue("generated java code doesn't exist",
+ new File(testRootDir, "shared/SharedService.java").exists());
+ assertTrue("generated java code doesn't exist",
+ new File(testRootDir, "tutorial/InvalidOperation.java").exists());
+ }
+
+ @Test
+ public void testBadCompile() throws Exception {
+ final File thriftFile = new File(testRootDir, "missing.thrift");
+ builder.addThriftPathElement(testRootDir);
+
+ // Hacking around checks in addThrift file.
+ assertTrue(thriftFile.createNewFile());
+ builder.addThriftFile(thriftFile);
+ assertTrue(thriftFile.delete());
+
+ final Thrift thrift = builder.build();
+
+ assertTrue(!thriftFile.exists());
+ assertFalse("gen-java directory should not exist", genJavaDir.exists());
+
+ // execute the compile
+ final int result = thrift.compile();
+ assertEquals(1, result);
+ }
+
+ @Test
+ public void testFileInPathPreCondition() throws Exception {
+ final File thriftFile = new File(testRootDir, "missing.thrift");
+
+ // Hacking around checks in addThrift file.
+ assertTrue(thriftFile.createNewFile());
+ try {
+ builder.addThriftFile(thriftFile);
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException e) {
+ }
+ }
+
+ @After
+ public void cleanup() throws Exception {
+ if (testRootDir.exists()) {
+ FileUtils.cleanDirectory(testRootDir);
+ assertTrue("Failed to delete output directory for test: " + testRootDir.getPath(), testRootDir.delete());
+ }
+ }
+}
diff --git a/contrib/thrift-maven-plugin/src/test/resources/idl/shared.thrift b/contrib/thrift-maven-plugin/src/test/resources/idl/shared.thrift
new file mode 100644
index 000000000..475e7f803
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/test/resources/idl/shared.thrift
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * This Thrift file can be included by other Thrift files that want to share
+ * these definitions.
+ */
+
+namespace cpp shared
+namespace java shared
+namespace perl shared
+
+struct SharedStruct {
+ 1: i32 key
+ 2: string value
+}
+
+service SharedService {
+ SharedStruct getStruct(1: i32 key)
+}
diff --git a/contrib/thrift-maven-plugin/src/test/resources/idl/tutorial.thrift b/contrib/thrift-maven-plugin/src/test/resources/idl/tutorial.thrift
new file mode 100644
index 000000000..86e433dd3
--- /dev/null
+++ b/contrib/thrift-maven-plugin/src/test/resources/idl/tutorial.thrift
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+# Thrift Tutorial
+# Mark Slee (mcslee@facebook.com)
+#
+# This file aims to teach you how to use Thrift, in a .thrift file. Neato. The
+# first thing to notice is that .thrift files support standard shell comments.
+# This lets you make your thrift file executable and include your Thrift build
+# step on the top line. And you can place comments like this anywhere you like.
+#
+# Before running this file, you will need to have installed the thrift compiler
+# into /usr/local/bin.
+
+/**
+ * The first thing to know about are types. The available types in Thrift are:
+ *
+ * bool Boolean, one byte
+ * byte Signed byte
+ * i16 Signed 16-bit integer
+ * i32 Signed 32-bit integer
+ * i64 Signed 64-bit integer
+ * double 64-bit floating point value
+ * string String
+ * binary Blob (byte array)
+ * map<t1,t2> Map from one type to another
+ * list<t1> Ordered list of one type
+ * set<t1> Set of unique elements of one type
+ *
+ * Did you also notice that Thrift supports C style comments?
+ */
+
+// Just in case you were wondering... yes. We support simple C comments too.
+
+/**
+ * Thrift files can reference other Thrift files to include common struct
+ * and service definitions. These are found using the current path, or by
+ * searching relative to any paths specified with the -I compiler flag.
+ *
+ * Included objects are accessed using the name of the .thrift file as a
+ * prefix. i.e. shared.SharedObject
+ */
+include "shared.thrift"
+
+/**
+ * Thrift files can namespace, package, or prefix their output in various
+ * target languages.
+ */
+namespace cpp tutorial
+namespace java tutorial
+namespace php tutorial
+namespace perl tutorial
+namespace smalltalk.category Thrift.Tutorial
+
+/**
+ * Thrift lets you do typedefs to get pretty names for your types. Standard
+ * C style here.
+ */
+typedef i32 MyInteger
+
+/**
+ * Thrift also lets you define constants for use across languages. Complex
+ * types and structs are specified using JSON notation.
+ */
+const i32 INT32CONSTANT = 9853
+const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
+
+/**
+ * You can define enums, which are just 32 bit integers. Values are optional
+ * and start at 1 if not supplied, C style again.
+ */
+enum Operation {
+ ADD = 1,
+ SUBTRACT = 2,
+ MULTIPLY = 3,
+ DIVIDE = 4
+}
+
+/**
+ * Structs are the basic complex data structures. They are comprised of fields
+ * which each have an integer identifier, a type, a symbolic name, and an
+ * optional default value.
+ *
+ * Fields can be declared "optional", which ensures they will not be included
+ * in the serialized output if they aren't set. Note that this requires some
+ * manual management in some languages.
+ */
+struct Work {
+ 1: i32 num1 = 0,
+ 2: i32 num2,
+ 3: Operation op,
+ 4: optional string comment,
+}
+
+/**
+ * Structs can also be exceptions, if they are nasty.
+ */
+exception InvalidOperation {
+ 1: i32 what,
+ 2: string why
+}
+
+/**
+ * Ahh, now onto the cool part, defining a service. Services just need a name
+ * and can optionally inherit from another service using the extends keyword.
+ */
+service Calculator extends shared.SharedService {
+
+ /**
+ * A method definition looks like C code. It has a return type, arguments,
+ * and optionally a list of exceptions that it may throw. Note that argument
+ * lists and exception lists are specified using the exact same syntax as
+ * field lists in struct or exception definitions.
+ */
+
+ void ping(),
+
+ i32 add(1:i32 num1, 2:i32 num2),
+
+ i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
+
+ /**
+ * This method has a oneway modifier. That means the client only makes
+ * a request and does not listen for any response at all. Oneway methods
+ * must be void.
+ */
+ oneway void zip()
+
+}
+
+/**
+ * That just about covers the basics. Take a look in the test/ folder for more
+ * detailed examples. After you run this file, your generated code shows up
+ * in folders with names gen-<language>. The generated code isn't too scary
+ * to look at. It even has pretty indentation.
+ */
diff --git a/contrib/thrift.el b/contrib/thrift.el
index cd3e0e891..941a99fe4 100644
--- a/contrib/thrift.el
+++ b/contrib/thrift.el
@@ -1,4 +1,7 @@
-;;
+;;; thrift.el --- Major mode for Apache Thrift files
+
+;; Keywords: files
+
;; 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
@@ -17,9 +20,16 @@
;; under the License.
;;
+;;; Commentary:
+
+;;
+
+;;; Code:
+
(require 'font-lock)
(defvar thrift-mode-hook nil)
+;;;###autoload
(add-to-list 'auto-mode-alist '("\\.thrift\\'" . thrift-mode))
(defvar thrift-indent-level 2
@@ -28,13 +38,12 @@
;; syntax coloring
(defconst thrift-font-lock-keywords
(list
- '("#.*$" . font-lock-comment-face) ;; perl style comments
'("\\<\\(include\\|struct\\|exception\\|typedef\\|const\\|enum\\|service\\|extends\\|void\\|oneway\\|throws\\|optional\\|required\\)\\>" . font-lock-keyword-face) ;; keywords
'("\\<\\(bool\\|byte\\|i16\\|i32\\|i64\\|double\\|string\\|binary\\|map\\|list\\|set\\)\\>" . font-lock-type-face) ;; built-in types
'("\\<\\([0-9]+\\)\\>" . font-lock-variable-name-face) ;; ordinals
'("\\<\\(\\w+\\)\\s-*(" (1 font-lock-function-name-face)) ;; functions
)
- "Thrift Keywords")
+ "Thrift Keywords.")
;; indentation
(defun thrift-indent-line ()
@@ -102,18 +111,20 @@
(indent-line-to cur-indent)
(indent-line-to 0)))))
-;; C/C++ comments; also allowing underscore in words
+;; C/C++- and sh-style comments; also allowing underscore in words
(defvar thrift-mode-syntax-table
(let ((thrift-mode-syntax-table (make-syntax-table)))
(modify-syntax-entry ?_ "w" thrift-mode-syntax-table)
- (modify-syntax-entry ?/ ". 1456" thrift-mode-syntax-table)
- (modify-syntax-entry ?* ". 23" thrift-mode-syntax-table)
- (modify-syntax-entry ?\n "> b" thrift-mode-syntax-table)
+ (modify-syntax-entry ?# "<" thrift-mode-syntax-table) ; sh-style comments
+ (modify-syntax-entry ?/ ". 124" thrift-mode-syntax-table) ; c/c++-style comments
+ (modify-syntax-entry ?* ". 23b" thrift-mode-syntax-table)
+ (modify-syntax-entry ?\n ">" thrift-mode-syntax-table)
thrift-mode-syntax-table)
"Syntax table for thrift-mode")
+;;;###autoload
(defun thrift-mode ()
- "Mode for editing Thrift files"
+ "Mode for editing Thrift files."
(interactive)
(kill-all-local-variables)
(set-syntax-table thrift-mode-syntax-table)
@@ -123,4 +134,7 @@
(run-hooks 'thrift-mode-hook)
(set (make-local-variable 'indent-line-function) 'thrift-indent-line)
)
-(provide 'thrift-mode)
+
+(provide 'thrift)
+;;; thrift.el ends here
+
diff --git a/contrib/thrift.spec b/contrib/thrift.spec
index d95a50264..cc3c33c8e 100644
--- a/contrib/thrift.spec
+++ b/contrib/thrift.spec
@@ -17,6 +17,10 @@
# under the License.
#
+%define without_java 1
+%define without_python 1
+%define without_tests 1
+
%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
@@ -24,7 +28,7 @@ Name: thrift
License: Apache License v2.0
Group: Development
Summary: RPC and serialization framework
-Version: 0.9.1
+Version: 1.0.0
Release: 0
URL: http://thrift.apache.org
Packager: Thrift Developers <dev@thrift.apache.org>
@@ -42,6 +46,12 @@ BuildRequires: ant >= 0:1.6.5
BuildRequires: python-devel
%endif
+%if 0%{!?without_ruby:1}
+%define gem_name %{name}
+BuildRequires: ruby-devel
+BuildRequires: rubygems-devel
+%endif
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
@@ -120,19 +130,68 @@ Python libraries for Thrift.
%endif
+%if 0%{!?without_ruby:1}
+%package -n rubygem-%{gem_name}
+Summary: Thrift Ruby library
+Group: Libraries
+Obsoletes: %{name}-lib-ruby
+
+%description -n rubygem-%{gem_name}
+Ruby libraries for Thrift.
+
+%files -n rubygem-%{gem_name}
+%defattr(-,root,root)
+%{gem_dir}/*
+%endif
+
+
+%if 0%{!?without_php:1}
+%package lib-php
+Summary: Thrift PHP library
+Group: Libraries
+
+%description lib-php
+PHP libraries for Thrift.
+
+%files lib-php
+%defattr(-,root,root)
+/usr/lib/php/*
+%endif
+
+
%prep
%setup -q
%build
+[[ -e Makefile.in ]] || ./bootstrap.sh
+export GEM_HOME=${PWD}/.gem-home
+export RUBYLIB=${PWD}/lib/rb/lib
%configure \
%{?without_libevent: --without-libevent } \
%{?without_zlib: --without-zlib } \
- --without-java \
+ %{?without_tests: --without-tests } \
+ %{?without_java: --without-java } \
+ %{?without_python: --without-python } \
+ %{?without_ruby: --without-ruby } \
+ %{?without_php: --without-php } \
+ %{!?without_php: PHP_PREFIX=${RPM_BUILD_ROOT}/usr/lib/php } \
--without-csharp \
- --without-python \
--without-erlang \
-make
+%if 0%{!?without_ruby:1}
+eval $(grep "^WITH_RUBY_TRUE" config.log)
+if [[ "${WITH_RUBY_TRUE}" != "" ]]; then
+ set +x
+ echo ""
+ echo "configure determined that ruby requirements are missing (bundler gem?), either install missing components" >&2
+ echo "or disable the ruby sub-packages as follows:" >&2
+ echo " rpmbuild -D'%without_ruby 1' ..." >&2
+ echo ""
+ exit 1
+fi
+%endif
+
+make %{?_smp_mflags}
%if 0%{!?without_java:1}
cd lib/java
@@ -146,7 +205,13 @@ CFLAGS="%{optflags}" %{__python} setup.py build
cd ../..
%endif
+%if 0%{!?without_ruby:1}
+%gem_install -n lib/rb/thrift*.gem
+%endif
+
%install
+export GEM_HOME=${PWD}/.gem-home
+export RUBYLIB=${PWD}/lib/rb/lib
%makeinstall
ln -s libthrift-%{version}.so ${RPM_BUILD_ROOT}%{_libdir}/libthrift.so.0
ln -s libthriftnb-%{version}.so ${RPM_BUILD_ROOT}%{_libdir}/libthriftnb.so.0
@@ -154,7 +219,7 @@ ln -s libthriftz-%{version}.so ${RPM_BUILD_ROOT}%{_libdir}/libthriftz.so.0
%if 0%{!?without_java:1}
mkdir -p $RPM_BUILD_ROOT%{_javadir}
-cp -p lib/java/*.jar $RPM_BUILD_ROOT%{_javadir}
+cp -p lib/java/build/*.jar $RPM_BUILD_ROOT%{_javadir}
%endif
%if 0%{!?without_python:1}
@@ -163,6 +228,10 @@ cd lib/py
cd ../..
%endif
+%if 0%{!?without_ruby:1}
+mkdir -p %{buildroot}%{gem_dir}
+cp -a ./%{gem_dir}/* %{buildroot}%{gem_dir}/
+%endif
%clean
rm -rf ${RPM_BUILD_ROOT}
diff --git a/contrib/thrift.vim b/contrib/thrift.vim
index 79ce54720..623195577 100644
--- a/contrib/thrift.vim
+++ b/contrib/thrift.vim
@@ -51,8 +51,8 @@ syn match thriftNumber "-\=\<\d\+\>" contained
syn keyword thriftKeyword namespace
syn keyword thriftKeyword xsd_all xsd_optional xsd_nillable xsd_attrs
syn keyword thriftKeyword include cpp_include cpp_type const optional required
-syn keyword thriftBasicTypes void bool byte i16 i32 i64 double string binary
-syn keyword thriftStructure map list set struct typedef exception enum throws
+syn keyword thriftBasicTypes void bool byte i8 i16 i32 i64 double string binary
+syn keyword thriftStructure map list set struct typedef exception enum throws union
" Special
syn match thriftSpecial "\d\+:"
diff --git a/contrib/transport-sample/README.txt b/contrib/transport-sample/README.md
index a1dfc0a36..a1dfc0a36 100644
--- a/contrib/transport-sample/README.txt
+++ b/contrib/transport-sample/README.md
diff --git a/contrib/transport-sample/ThriftCommon.h b/contrib/transport-sample/ThriftCommon.h
index d24d1a7a7..e16d87ddd 100644
--- a/contrib/transport-sample/ThriftCommon.h
+++ b/contrib/transport-sample/ThriftCommon.h
@@ -16,8 +16,6 @@
//
#ifdef _WIN32 //thrift is crashing when using boost threads on Mac OSX
-# define USE_BOOST_THREAD 1
-# include <boost/thread.hpp>
#else
# include <sys/socket.h>
# include <netinet/in.h>
diff --git a/contrib/vagrant/centos-6.5/README.md b/contrib/vagrant/centos-6.5/README.md
new file mode 100644
index 000000000..55583f901
--- /dev/null
+++ b/contrib/vagrant/centos-6.5/README.md
@@ -0,0 +1,61 @@
+Apache Thrift Centos 6.5 Vagrant Support
+========================================
+This directory is the Vagrant project directory for Apache Thrift running on Centos 6.5. The Vagrantfile in this directory configures a Vagrant provisioned VM launched under VirtualBox. To use this project you must have a recent version of VirtualBox and Vagrant installed (in that order). To run the VM, open a shell, clone Apache Thrift, change to this directory and enter the Vagrant up command.
+
+ $ git clone https://github.com/apache/thrift
+ $ cd thrift/contrib/vagrant/centos-6.5
+ $ vagrant up
+
+This will download and launch the base box VM under VirtualBox and run the Apache Thrift provisioning script. This will take up to an hour depending on your hardware and network. Once complete you can login to the box with Vagrant ssh. The thrift source tree from your host os is mounted at /thrift.
+
+ $ vagrant ssh
+ [vagrant@thrift ~]$ cd /thrift
+ [vagrant@thrift thrift]$ compiler/cpp/thrift --version
+ Thrift version <version>
+
+The provisioning script (inside the Vagrantfile) runs ./bootstrap.sh, ./configure, make and make check, but does not install thrift. To install thrift run "make install".
+
+The Vagrant base box used here is a minimal Centos 6.5 VirtualBox with 2GB RAM and 2 CPUs. For more Vagrant information: https://www.vagrantup.com. A summary of the base box preparation follows:
+
+root password: vagrant
+
+#Create the vagrant user and give it sudo permission
+adduser vagrant
+passwd vagrant
+visudo : vagrant ALL=(ALL) NOPASSWD: ALL
+ #Defaults requiretty
+
+#Shut down the firewall and disable it
+service iptables stop
+chkconfig iptables off
+
+#Setup the vagrant ssh public key to allow vagrant to ssh
+mkdir /home/vagrant/.ssh
+chmod 700 /home/vagrant/.ssh
+cd /home/vagrant/.ssh
+wget --no-check-certificate 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' -O authorized_keys
+chmod 600 /home/vagrant/.ssh/authorized_keys
+chown -R vagrant /home/vagrant/.ssh
+
+#Install EPEL (Extra Packages for Enterprise Linux) but protect the base
+#repositories so that EPEL does not mask base packages
+yum -y install yum-plugin-protectbase
+rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
+
+#Install perl, dynamic kernel modules, dev tools and kernel headers to support
+#Virtual box additions
+yum -y install perl
+yum -y --enablerepo epel install dkms
+yum -y groupinstall "Development Tools"
+yum -y install kernel-devel
+
+#Update everything and reboot
+yum update
+reboot
+
+#Install the VirtualBox Guest additions (using VirtualBox iso)
+mount /dev/cdrom /mnt
+/mnt/VBoxLinuxAdditions.run
+umount /mnt
+
+See the Vagrantfile for further details
diff --git a/contrib/vagrant/centos-6.5/Vagrantfile b/contrib/vagrant/centos-6.5/Vagrantfile
new file mode 100644
index 000000000..51a2239bc
--- /dev/null
+++ b/contrib/vagrant/centos-6.5/Vagrantfile
@@ -0,0 +1,274 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# 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.
+
+# APACHE THRIFT PROVISIONING SCRIPT
+##############################################################
+# This script is used to configure the base Centos 6.5
+# Vagrant box for Apache Thrift compiler and lib builds.
+# The base box is Centos 6.5 with no additional packages
+# except those required to support VirtualBox Guest tools:
+# perl, dkms, kernel-devel and the "Development Tools" group.
+# The epel repo was also added along with the
+# yum-plugin-protectbase package to prefer base repo packages.
+# The script below provisions ALL languages. This will take
+# time. You can greatly reduce the build time by commenting
+# out the LIB provisioning for uneeded language libraries.
+# Expect full provisioning to take 30 minutes on a fast
+# machine with an excellent Internet connection (and another
+# 15 minutes for the build).
+#
+# Machine accounts:
+# - User: vagrant/vagrant
+# - Admin: root/vagrant
+# Vagrant public ssh key also installed
+##############################################################
+
+$build_and_test = <<SCRIPT
+echo "Provisioning system to compile and test Apache Thrift."
+date > /etc/vagrant.provision_begin
+
+# Apache Thrift compiler dependencies
+#####################################
+
+#install an updated autoconf
+wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
+tar xvf autoconf-2.69.tar.gz
+cd autoconf-2.69
+./configure --prefix=/usr
+make
+sudo make install
+cd ..
+
+#install an updated automake
+wget http://ftp.gnu.org/gnu/automake/automake-1.14.tar.gz
+tar xvf automake-1.14.tar.gz
+cd automake-1.14
+./configure --prefix=/usr
+make
+sudo make install
+cd ..
+
+#install an updated bison
+wget http://ftp.gnu.org/gnu/bison/bison-2.5.1.tar.gz
+tar xvf bison-2.5.1.tar.gz
+cd bison-2.5.1
+./configure --prefix=/usr
+make
+sudo make install
+cd ..
+
+# C++98 LIB Dependencies
+#####################################
+sudo yum -y install libevent-devel zlib-devel openssl-devel
+
+#Install an updated Boost library
+wget http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.tar.gz
+tar xvf boost_1_55_0.tar.gz
+cd boost_1_55_0
+./bootstrap.sh
+sudo ./b2 install
+
+# Java LIB Dependencies
+#####################################
+sudo yum install -y ant junit ant-nodeps ant-junit java-1.8.0-openjdk-devel
+
+# Python LIB Dependencies
+#####################################
+sudo yum install -y python-devel python-setuptools python-twisted
+
+# Ruby LIB Dependencies
+#####################################
+sudo yum install -y ruby ruby-devel rubygems
+sudo gem install bundler rake
+
+# Node.js LIB Dependencies
+#####################################
+sudo yum install -y nodejs nodejs-devel npm
+
+# Perl LIB Dependencies
+#####################################
+sudo yum install -y perl-Bit-Vector perl-Class-Accessor perl-ExtUtils-MakeMaker perl-Test-Simple
+
+# PHP LIB Dependencies
+#####################################
+sudo yum install -y php php-devel php-pear re2c
+
+# GLibC LIB Dependencies
+#####################################
+sudo yum install -y glib2-devel
+
+# Erlang LIB Dependencies
+#####################################
+sudo yum install -y erlang-kernel erlang-erts erlang-stdlib erlang-eunit erlang-rebar
+
+# Lua LIB Dependencies
+#####################################
+sudo yum install -y lua-devel
+
+# Go LIB Dependencies
+#####################################
+sudo yum install -y golang golang-pkg-linux-amd64
+
+# C# LIB Dependencies
+#####################################
+sudo yum install -y mono-core mono-devel mono-web-devel mono-extras mingw32-binutils mingw32-runtime mingw32-nsis
+
+# Haskell LIB Dependencies
+#####################################
+wget http://sherkin.justhub.org/el6/RPMS/x86_64/justhub-release-2.0-4.0.el6.x86_64.rpm
+sudo rpm -ivh justhub-release-2.0-4.0.el6.x86_64.rpm
+sudo yum -y install haskell
+sudo cabal update
+sudo cabal install cabal-install
+
+# Build and Test Apache Thrift
+#####################################
+date > /etc/vagrant.provision_end
+echo "Starting Apache Thrift build..."
+cd /thrift
+sh bootstrap.sh
+
+# At the time of this file's creation Ruby, Python, Go and Lua fail
+# their unit tests in this environment. To build and test any of these
+# libraries uncomment the appropriate --without switches below.
+
+sh configure --without-ruby --without-go --without-lua --without-python
+make
+echo "Starting Apache Thrift tests..."
+make check
+echo "Finished building and testing Apache Thrift."
+echo 'Use "make install" to install the compiler and libraries.'
+date > /etc/vagrant.make_end
+
+SCRIPT
+
+Vagrant.configure("2") do |config|
+ # Every Vagrant virtual environment requires a box to build off of.
+ ##### Centos 6.5 minimal system with VirtualBox Guest Additions
+ ##### Box maintained by ra@apache.org, see README.md for box config
+ config.vm.box = "RandyAbernethy/thrift-centos-6.5-64"
+
+ # Disable automatic box update checking. If you disable this, then
+ # boxes will only be checked for updates when the user runs
+ # `vagrant box outdated`. This is not recommended.
+ ##### This box will never change
+ config.vm.box_check_update = false
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine. In the example below,
+ # accessing "localhost:8080" will access port 80 on the guest machine.
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
+
+ # Create a private network, which allows host-only access to the machine
+ # using a specific IP.
+ # config.vm.network "private_network", ip: "192.168.33.10"
+
+ # Create a public network, which generally matched to bridged network.
+ # Bridged networks make the machine appear as another physical device on
+ # your network.
+ # config.vm.network "public_network"
+
+ # If true, then any SSH connections made will enable agent forwarding.
+ # Default value: false
+ # config.ssh.forward_agent = true
+
+ # Share an additional folder to the guest VM. The first argument is
+ # the path on the host to the actual folder. The second argument is
+ # the path on the guest to mount the folder. And the optional third
+ # argument is a set of non-required options.
+ # config.vm.synced_folder "../data", "/vagrant_data"
+ ##### By convention the thrift source tree is mapped to /thrift
+ config.vm.synced_folder "../../../", "/thrift"
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ ##### The machine needs 2 CPUs and 2GB RAM for reasonable performance
+ config.vm.provider "virtualbox" do |vb|
+ vb.customize ["modifyvm", :id, "--memory", "2048"]
+ vb.customize ["modifyvm", :id, "--cpus", "2"]
+ end
+
+ # Enable provisioning with CFEngine. CFEngine Community packages are
+ # automatically installed. For example, configure the host as a
+ # policy server and optionally a policy file to run:
+ #
+ # config.vm.provision "cfengine" do |cf|
+ # cf.am_policy_hub = true
+ # # cf.run_file = "motd.cf"
+ # end
+ #
+ # You can also configure and bootstrap a client to an existing
+ # policy server:
+ #
+ # config.vm.provision "cfengine" do |cf|
+ # cf.policy_server_address = "10.0.2.15"
+ # end
+
+ # Enable provisioning with Puppet stand alone. Puppet manifests
+ # are contained in a directory path relative to this Vagrantfile.
+ # You will need to create the manifests directory and a manifest in
+ # the file default.pp in the manifests_path directory.
+ #
+ # config.vm.provision "puppet" do |puppet|
+ # puppet.manifests_path = "manifests"
+ # puppet.manifest_file = "default.pp"
+ # end
+
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
+ # some recipes and/or roles.
+ #
+ # config.vm.provision "chef_solo" do |chef|
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
+ # chef.roles_path = "../my-recipes/roles"
+ # chef.data_bags_path = "../my-recipes/data_bags"
+ # chef.add_recipe "mysql"
+ # chef.add_role "web"
+ #
+ # # You may also specify custom JSON attributes:
+ # chef.json = { mysql_password: "foo" }
+ # end
+
+ # Enable provisioning with chef server, specifying the chef server URL,
+ # and the path to the validation key (relative to this Vagrantfile).
+ #
+ # The Opscode Platform uses HTTPS. Substitute your organization for
+ # ORGNAME in the URL and validation key.
+ #
+ # If you have your own Chef Server, use the appropriate URL, which may be
+ # HTTP instead of HTTPS depending on your configuration. Also change the
+ # validation key to validation.pem.
+ #
+ # config.vm.provision "chef_client" do |chef|
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
+ # chef.validation_key_path = "ORGNAME-validator.pem"
+ # end
+ #
+ # If you're using the Opscode platform, your validator client is
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
+ #
+ # If you have your own Chef Server, the default validation client name is
+ # chef-validator, unless you changed the configuration.
+ #
+ # chef.validation_client_name = "ORGNAME-validator"
+
+ ##### Run the Apache Thrift provisioning script (declared above)
+ config.vm.provision :shell, :inline => $build_and_test
+end
diff --git a/contrib/zeromq/Makefile b/contrib/zeromq/Makefile
index a1d71568d..ee398e22c 100644
--- a/contrib/zeromq/Makefile
+++ b/contrib/zeromq/Makefile
@@ -1,6 +1,4 @@
THRIFT = thrift
-CXXFLAGS = `pkg-config --cflags libzmq thrift`
-LDLIBS = `pkg-config --libs libzmq thrift`
CXXFLAGS += -g3 -O0
@@ -16,15 +14,19 @@ PROGS = test-client test-server test-sender test-receiver
all: $(PYLIBS) $(PROGS)
test-client: test-client.o TZmqClient.o $(GENOBJS)
+ $(CXX) $^ -o $@ -lzmq -lthrift
test-server: test-server.o TZmqServer.o $(GENOBJS)
+ $(CXX) $^ -o $@ -lzmq -lthrift
test-sender: test-sender.o TZmqClient.o $(GENOBJS)
+ $(CXX) $^ -o $@ -lzmq -lthrift
test-receiver: test-receiver.o TZmqServer.o $(GENOBJS)
+ $(CXX) $^ -o $@ -lzmq -lthrift
test-client.o test-server.o test-sender.o test-receiver.o: $(GENSRCS)
storage/__init__.py: storage.thrift
$(RM) $(dir $@)
- $(THRIFT) --gen py:newstyle $<
+ $(THRIFT) --gen py $<
mv gen-py/$(dir $@) .
$(GENSRCS): storage.thrift
diff --git a/contrib/zeromq/README b/contrib/zeromq/README.md
index 9e0b5bd32..9e0b5bd32 100644
--- a/contrib/zeromq/README
+++ b/contrib/zeromq/README.md
diff --git a/contrib/zeromq/TZmqClient.cpp b/contrib/zeromq/TZmqClient.cpp
index 133204e34..56278f325 100644
--- a/contrib/zeromq/TZmqClient.cpp
+++ b/contrib/zeromq/TZmqClient.cpp
@@ -22,7 +22,7 @@
namespace apache { namespace thrift { namespace transport {
-uint32_t TZmqClient::read(uint8_t* buf, uint32_t len) {
+uint32_t TZmqClient::read_virt(uint8_t* buf, uint32_t len) {
if (rbuf_.available_read() == 0) {
(void)sock_.recv(&msg_);
rbuf_.resetBuffer((uint8_t*)msg_.data(), msg_.size());
@@ -30,11 +30,11 @@ uint32_t TZmqClient::read(uint8_t* buf, uint32_t len) {
return rbuf_.read(buf, len);
}
-void TZmqClient::write(const uint8_t* buf, uint32_t len) {
+void TZmqClient::write_virt(const uint8_t* buf, uint32_t len) {
return wbuf_.write(buf, len);
}
-void TZmqClient::writeEnd() {
+uint32_t TZmqClient::writeEnd() {
uint8_t* buf;
uint32_t size;
wbuf_.getBuffer(&buf, &size);
@@ -42,6 +42,7 @@ void TZmqClient::writeEnd() {
std::memcpy(msg.data(), buf, size);
(void)sock_.send(msg);
wbuf_.resetBuffer(true);
+ return size;
}
}}} // apache::thrift::transport
diff --git a/contrib/zeromq/TZmqClient.h b/contrib/zeromq/TZmqClient.h
index 9fcfc06a6..df16e03af 100644
--- a/contrib/zeromq/TZmqClient.h
+++ b/contrib/zeromq/TZmqClient.h
@@ -45,15 +45,15 @@ class TZmqClient : public TTransport {
}
}
- uint32_t read(uint8_t* buf, uint32_t len);
+ uint32_t read_virt(uint8_t* buf, uint32_t len);
- void write(const uint8_t* buf, uint32_t len);
+ void write_virt(const uint8_t* buf, uint32_t len);
- void writeEnd();
+ uint32_t writeEnd();
protected:
- std::string endpoint_;
zmq::socket_t sock_;
+ std::string endpoint_;
TMemoryBuffer wbuf_;
TMemoryBuffer rbuf_;
zmq::message_t msg_;
diff --git a/contrib/zeromq/TZmqClient.py b/contrib/zeromq/TZmqClient.py
index d56069733..1bd60a1e5 100644
--- a/contrib/zeromq/TZmqClient.py
+++ b/contrib/zeromq/TZmqClient.py
@@ -20,44 +20,45 @@ import zmq
from cStringIO import StringIO
from thrift.transport.TTransport import TTransportBase, CReadableTransport
+
class TZmqClient(TTransportBase, CReadableTransport):
- def __init__(self, ctx, endpoint, sock_type):
- self._sock = ctx.socket(sock_type)
- self._endpoint = endpoint
- self._wbuf = StringIO()
- self._rbuf = StringIO()
-
- def open(self):
- self._sock.connect(self._endpoint)
-
- def read(self, size):
- ret = self._rbuf.read(size)
- if len(ret) != 0:
- return ret
- self._read_message()
- return self._rbuf.read(size)
-
- def _read_message(self):
- msg = self._sock.recv()
- self._rbuf = StringIO(msg)
-
- def write(self, buf):
- self._wbuf.write(buf)
-
- def flush(self):
- msg = self._wbuf.getvalue()
- self._wbuf = StringIO()
- self._sock.send(msg)
-
- # Implement the CReadableTransport interface.
- @property
- def cstringio_buf(self):
- return self._rbuf
-
- # NOTE: This will probably not actually work.
- def cstringio_refill(self, prefix, reqlen):
- while len(prefix) < reqlen:
- self.read_message()
- prefix += self._rbuf.getvalue()
- self._rbuf = StringIO(prefix)
- return self._rbuf
+ def __init__(self, ctx, endpoint, sock_type):
+ self._sock = ctx.socket(sock_type)
+ self._endpoint = endpoint
+ self._wbuf = StringIO()
+ self._rbuf = StringIO()
+
+ def open(self):
+ self._sock.connect(self._endpoint)
+
+ def read(self, size):
+ ret = self._rbuf.read(size)
+ if len(ret) != 0:
+ return ret
+ self._read_message()
+ return self._rbuf.read(size)
+
+ def _read_message(self):
+ msg = self._sock.recv()
+ self._rbuf = StringIO(msg)
+
+ def write(self, buf):
+ self._wbuf.write(buf)
+
+ def flush(self):
+ msg = self._wbuf.getvalue()
+ self._wbuf = StringIO()
+ self._sock.send(msg)
+
+ # Implement the CReadableTransport interface.
+ @property
+ def cstringio_buf(self):
+ return self._rbuf
+
+ # NOTE: This will probably not actually work.
+ def cstringio_refill(self, prefix, reqlen):
+ while len(prefix) < reqlen:
+ self.read_message()
+ prefix += self._rbuf.getvalue()
+ self._rbuf = StringIO(prefix)
+ return self._rbuf
diff --git a/contrib/zeromq/TZmqServer.cpp b/contrib/zeromq/TZmqServer.cpp
index f255a66ee..88660a330 100644
--- a/contrib/zeromq/TZmqServer.cpp
+++ b/contrib/zeromq/TZmqServer.cpp
@@ -21,13 +21,12 @@
#include <thrift/transport/TBufferTransports.h>
#include <boost/scoped_ptr.hpp>
-using boost::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::protocol::TProtocol;
namespace apache { namespace thrift { namespace server {
-
bool TZmqServer::serveOne(int recv_flags) {
zmq::message_t msg;
bool received = sock_.recv(&msg, recv_flags);
@@ -40,8 +39,9 @@ bool TZmqServer::serveOne(int recv_flags) {
inputProtocolFactory_->getProtocol(inputTransport));
shared_ptr<TProtocol> outputProtocol(
outputProtocolFactory_->getProtocol(outputTransport));
+ shared_ptr<TMemoryBuffer> transport(new TMemoryBuffer);
- processor_->process(inputProtocol, outputProtocol);
+ processor_->process(inputProtocol, outputProtocol, NULL);
if (zmq_type_ == ZMQ_REP) {
uint8_t* buf;
diff --git a/contrib/zeromq/TZmqServer.h b/contrib/zeromq/TZmqServer.h
index f91c6e8b3..ecd13b424 100644
--- a/contrib/zeromq/TZmqServer.h
+++ b/contrib/zeromq/TZmqServer.h
@@ -20,6 +20,7 @@
#ifndef _THRIFT_SERVER_TZMQSERVER_H_
#define _THRIFT_SERVER_TZMQSERVER_H_ 1
+#include <memory>
#include <zmq.hpp>
#include <thrift/server/TServer.h>
@@ -28,9 +29,10 @@ namespace apache { namespace thrift { namespace server {
class TZmqServer : public TServer {
public:
TZmqServer(
- boost::shared_ptr<TProcessor> processor,
+ std::shared_ptr<TProcessor> processor,
zmq::context_t& ctx, const std::string& endpoint, int type)
: TServer(processor)
+ , processor_(processor)
, zmq_type_(type)
, sock_(ctx, type)
{
@@ -55,6 +57,7 @@ class TZmqServer : public TServer {
}
private:
+ std::shared_ptr<TProcessor> processor_;
int zmq_type_;
zmq::socket_t sock_;
};
diff --git a/contrib/zeromq/TZmqServer.py b/contrib/zeromq/TZmqServer.py
index c83cc8d5d..15c1543ac 100644
--- a/contrib/zeromq/TZmqServer.py
+++ b/contrib/zeromq/TZmqServer.py
@@ -21,58 +21,59 @@ import zmq
import thrift.server.TServer
import thrift.transport.TTransport
+
class TZmqServer(thrift.server.TServer.TServer):
- def __init__(self, processor, ctx, endpoint, sock_type):
- thrift.server.TServer.TServer.__init__(self, processor, None)
- self.zmq_type = sock_type
- self.socket = ctx.socket(sock_type)
- self.socket.bind(endpoint)
+ def __init__(self, processor, ctx, endpoint, sock_type):
+ thrift.server.TServer.TServer.__init__(self, processor, None)
+ self.zmq_type = sock_type
+ self.socket = ctx.socket(sock_type)
+ self.socket.bind(endpoint)
- def serveOne(self):
- msg = self.socket.recv()
- itrans = thrift.transport.TTransport.TMemoryBuffer(msg)
- otrans = thrift.transport.TTransport.TMemoryBuffer()
- iprot = self.inputProtocolFactory.getProtocol(itrans)
- oprot = self.outputProtocolFactory.getProtocol(otrans)
+ def serveOne(self):
+ msg = self.socket.recv()
+ itrans = thrift.transport.TTransport.TMemoryBuffer(msg)
+ otrans = thrift.transport.TTransport.TMemoryBuffer()
+ iprot = self.inputProtocolFactory.getProtocol(itrans)
+ oprot = self.outputProtocolFactory.getProtocol(otrans)
- try:
- self.processor.process(iprot, oprot)
- except Exception:
- logging.exception("Exception while processing request")
- # Fall through and send back a response, even if empty or incomplete.
+ try:
+ self.processor.process(iprot, oprot)
+ except Exception:
+ logging.exception("Exception while processing request")
+ # Fall through and send back a response, even if empty or incomplete.
- if self.zmq_type == zmq.REP:
- msg = otrans.getvalue()
- self.socket.send(msg)
+ if self.zmq_type == zmq.REP:
+ msg = otrans.getvalue()
+ self.socket.send(msg)
- def serve(self):
- while True:
- self.serveOne()
+ def serve(self):
+ while True:
+ self.serveOne()
class TZmqMultiServer(object):
- def __init__(self):
- self.servers = []
+ def __init__(self):
+ self.servers = []
- def serveOne(self, timeout = -1):
- self._serveActive(self._setupPoll(), timeout)
+ def serveOne(self, timeout=-1):
+ self._serveActive(self._setupPoll(), timeout)
- def serveForever(self):
- poll_info = self._setupPoll()
- while True:
- self._serveActive(poll_info, -1)
+ def serveForever(self):
+ poll_info = self._setupPoll()
+ while True:
+ self._serveActive(poll_info, -1)
- def _setupPoll(self):
- server_map = {}
- poller = zmq.Poller()
- for server in self.servers:
- server_map[server.socket] = server
- poller.register(server.socket, zmq.POLLIN)
- return (server_map, poller)
+ def _setupPoll(self):
+ server_map = {}
+ poller = zmq.Poller()
+ for server in self.servers:
+ server_map[server.socket] = server
+ poller.register(server.socket, zmq.POLLIN)
+ return (server_map, poller)
- def _serveActive(self, poll_info, timeout):
- (server_map, poller) = poll_info
- ready = dict(poller.poll())
- for sock, state in ready.items():
- assert (state & zmq.POLLIN) != 0
- server_map[sock].serveOne()
+ def _serveActive(self, poll_info, timeout):
+ (server_map, poller) = poll_info
+ ready = dict(poller.poll())
+ for sock, state in ready.items():
+ assert (state & zmq.POLLIN) != 0
+ server_map[sock].serveOne()
diff --git a/contrib/zeromq/csharp/AssemblyInfo.cs b/contrib/zeromq/csharp/AssemblyInfo.cs
index 9ad48c61f..12cd434f3 100644
--- a/contrib/zeromq/csharp/AssemblyInfo.cs
+++ b/contrib/zeromq/csharp/AssemblyInfo.cs
@@ -14,20 +14,20 @@
* "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.
- */
+ * under the License.
+ */
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
+// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("ZmqServer")]
[assembly: AssemblyDescription("Zmq Examples")]
-[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("The Apache Software Foundation")]
-[assembly: AssemblyProduct("")]
+[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("The Apache Software Foundation")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -38,7 +38,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyVersion("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly,
+// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
diff --git a/contrib/zeromq/csharp/TZmqClient.cs b/contrib/zeromq/csharp/TZmqClient.cs
index c792882cd..e9ab5166a 100644
--- a/contrib/zeromq/csharp/TZmqClient.cs
+++ b/contrib/zeromq/csharp/TZmqClient.cs
@@ -47,7 +47,7 @@ namespace ZmqClient
throw new NotImplementedException ();
if (_rbuf.Length == 0) {
- //Fill the Buffer with the complete ZMQ Message which needs to be(?!) the complete Thrift reponse
+ //Fill the Buffer with the complete ZMQ Message which needs to be(?!) the complete Thrift response
debug ("Client_Read Filling buffer..");
byte[] tmpBuf = _sock.Recv ();
debug (string.Format("Client_Read filled with {0}b",tmpBuf.Length));
diff --git a/contrib/zeromq/csharp/ThriftZMQ.csproj b/contrib/zeromq/csharp/ThriftZMQ.csproj
index 1d5f13cb4..80ad1dbd6 100755
--- a/contrib/zeromq/csharp/ThriftZMQ.csproj
+++ b/contrib/zeromq/csharp/ThriftZMQ.csproj
@@ -1,91 +1,91 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <RootNamespace>ZmqServer</RootNamespace>
- <AssemblyName>ThriftZMQ</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>3.5</OldToolsVersion>
- <UpgradeBackupLocation />
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <DefineConstants>DEBUG</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <PlatformTarget>x86</PlatformTarget>
- <Externalconsole>true</Externalconsole>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>none</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <PlatformTarget>x86</PlatformTarget>
- <Externalconsole>true</Externalconsole>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="clrzmq, Version=2.1.0.0, Culture=neutral, processorArchitecture=x86">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>.\clrzmq.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="Thrift, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\lib\csharp\Thrift.dll</HintPath>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Main.cs" />
- <Compile Include="AssemblyInfo.cs" />
- <Compile Include="TZmqServer.cs" />
- <Compile Include="TZmqClient.cs" />
- <Compile Include="..\gen-csharp\Storage.cs" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-</Project> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>ZmqServer</RootNamespace>
+ <AssemblyName>ThriftZMQ</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.0</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <PlatformTarget>x86</PlatformTarget>
+ <Externalconsole>true</Externalconsole>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <PlatformTarget>x86</PlatformTarget>
+ <Externalconsole>true</Externalconsole>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="clrzmq, Version=2.1.0.0, Culture=neutral, processorArchitecture=x86">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>.\clrzmq.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="Thrift, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\lib\csharp\Thrift.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Main.cs" />
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="TZmqServer.cs" />
+ <Compile Include="TZmqClient.cs" />
+ <Compile Include="..\gen-csharp\Storage.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/contrib/zeromq/csharp/ThriftZMQ.sln b/contrib/zeromq/csharp/ThriftZMQ.sln
index 404a7476a..6af57b60c 100755
--- a/contrib/zeromq/csharp/ThriftZMQ.sln
+++ b/contrib/zeromq/csharp/ThriftZMQ.sln
@@ -1,42 +1,42 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftZMQ", "ThriftZMQ.csproj", "{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Debug|Mixed Platforms = Debug|Mixed Platforms
- Debug|x86 = Debug|x86
- Release|Any CPU = Release|Any CPU
- Release|Mixed Platforms = Release|Mixed Platforms
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Any CPU.ActiveCfg = Debug|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.Build.0 = Debug|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.ActiveCfg = Debug|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.Build.0 = Debug|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Any CPU.ActiveCfg = Release|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.Build.0 = Release|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.ActiveCfg = Release|x86
- {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.Build.0 = Release|x86
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|x86.ActiveCfg = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftZMQ", "ThriftZMQ.csproj", "{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.ActiveCfg = Debug|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.Build.0 = Debug|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Any CPU.ActiveCfg = Release|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.Build.0 = Release|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.ActiveCfg = Release|x86
+ {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.Build.0 = Release|x86
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|x86.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/zeromq/test-client.cpp b/contrib/zeromq/test-client.cpp
index d2fc56ce1..159c25030 100644
--- a/contrib/zeromq/test-client.cpp
+++ b/contrib/zeromq/test-client.cpp
@@ -6,7 +6,7 @@
#include "TZmqClient.h"
#include "Storage.h"
-using boost::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::transport::TZmqClient;
using apache::thrift::protocol::TBinaryProtocol;
@@ -17,7 +17,7 @@ int main(int argc, char** argv) {
if (argc > 1) {
incr = atoi(argv[1]);
if (incr) {
- socktype = ZMQ_DOWNSTREAM;
+ socktype = ZMQ_PUSH;
endpoint = "tcp://127.0.0.1:9091";
}
}
diff --git a/contrib/zeromq/test-client.py b/contrib/zeromq/test-client.py
index 1886d9cab..d51216e45 100755
--- a/contrib/zeromq/test-client.py
+++ b/contrib/zeromq/test-client.py
@@ -9,28 +9,28 @@ import storage.Storage
def main(args):
- endpoint = "tcp://127.0.0.1:9090"
- socktype = zmq.REQ
- incr = 0
- if len(args) > 1:
- incr = int(args[1])
- if incr:
- socktype = zmq.DOWNSTREAM
- endpoint = "tcp://127.0.0.1:9091"
+ endpoint = "tcp://127.0.0.1:9090"
+ socktype = zmq.REQ
+ incr = 0
+ if len(args) > 1:
+ incr = int(args[1])
+ if incr:
+ socktype = zmq.PUSH
+ endpoint = "tcp://127.0.0.1:9091"
- ctx = zmq.Context()
- transport = TZmqClient.TZmqClient(ctx, endpoint, socktype)
- protocol = thrift.protocol.TBinaryProtocol.TBinaryProtocolAccelerated(transport)
- client = storage.Storage.Client(protocol)
- transport.open()
+ ctx = zmq.Context()
+ transport = TZmqClient.TZmqClient(ctx, endpoint, socktype)
+ protocol = thrift.protocol.TBinaryProtocol.TBinaryProtocolAccelerated(transport)
+ client = storage.Storage.Client(protocol)
+ transport.open()
- if incr:
- client.incr(incr)
- time.sleep(0.05)
- else:
- value = client.get()
- print value
+ if incr:
+ client.incr(incr)
+ time.sleep(0.05)
+ else:
+ value = client.get()
+ print(value)
if __name__ == "__main__":
- main(sys.argv)
+ main(sys.argv)
diff --git a/contrib/zeromq/test-receiver.cpp b/contrib/zeromq/test-receiver.cpp
index 8fe69da92..d465bff63 100644
--- a/contrib/zeromq/test-receiver.cpp
+++ b/contrib/zeromq/test-receiver.cpp
@@ -2,7 +2,7 @@
#include "TZmqServer.h"
#include "Storage.h"
-using boost::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::TProcessor;
using apache::thrift::server::TZmqServer;
using apache::thrift::server::TZmqMultiServer;
diff --git a/contrib/zeromq/test-sender.cpp b/contrib/zeromq/test-sender.cpp
index 6b0eef156..5c086a11f 100644
--- a/contrib/zeromq/test-sender.cpp
+++ b/contrib/zeromq/test-sender.cpp
@@ -6,7 +6,7 @@
#include "TZmqClient.h"
#include "Storage.h"
-using boost::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::transport::TZmqClient;
using apache::thrift::protocol::TBinaryProtocol;
diff --git a/contrib/zeromq/test-server.cpp b/contrib/zeromq/test-server.cpp
index c624b0d8d..e6f1b2083 100644
--- a/contrib/zeromq/test-server.cpp
+++ b/contrib/zeromq/test-server.cpp
@@ -2,7 +2,7 @@
#include "TZmqServer.h"
#include "Storage.h"
-using boost::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::TProcessor;
using apache::thrift::server::TZmqServer;
using apache::thrift::server::TZmqMultiServer;
@@ -33,7 +33,7 @@ int main(int argc, char *argv[]) {
zmq::context_t ctx(1);
TZmqServer reqrep_server(processor, ctx, "tcp://0.0.0.0:9090", ZMQ_REP);
- TZmqServer oneway_server(processor, ctx, "tcp://0.0.0.0:9091", ZMQ_UPSTREAM);
+ TZmqServer oneway_server(processor, ctx, "tcp://0.0.0.0:9091", ZMQ_PULL);
TZmqMultiServer multiserver;
multiserver.servers().push_back(&reqrep_server);
multiserver.servers().push_back(&oneway_server);
diff --git a/contrib/zeromq/test-server.py b/contrib/zeromq/test-server.py
index 5767b71fe..d89b37ba2 100755
--- a/contrib/zeromq/test-server.py
+++ b/contrib/zeromq/test-server.py
@@ -6,28 +6,28 @@ import storage.Storage
class StorageHandler(storage.Storage.Iface):
- def __init__(self):
- self.value = 0
+ def __init__(self):
+ self.value = 0
- def incr(self, amount):
- self.value += amount
+ def incr(self, amount):
+ self.value += amount
- def get(self):
- return self.value
+ def get(self):
+ return self.value
def main():
- handler = StorageHandler()
- processor = storage.Storage.Processor(handler)
+ handler = StorageHandler()
+ processor = storage.Storage.Processor(handler)
- ctx = zmq.Context()
- reqrep_server = TZmqServer.TZmqServer(processor, ctx, "tcp://0.0.0.0:9090", zmq.REP)
- oneway_server = TZmqServer.TZmqServer(processor, ctx, "tcp://0.0.0.0:9091", zmq.UPSTREAM)
- multiserver = TZmqServer.TZmqMultiServer()
- multiserver.servers.append(reqrep_server)
- multiserver.servers.append(oneway_server)
- multiserver.serveForever()
+ ctx = zmq.Context()
+ reqrep_server = TZmqServer.TZmqServer(processor, ctx, "tcp://0.0.0.0:9090", zmq.REP)
+ oneway_server = TZmqServer.TZmqServer(processor, ctx, "tcp://0.0.0.0:9091", zmq.PULL)
+ multiserver = TZmqServer.TZmqMultiServer()
+ multiserver.servers.append(reqrep_server)
+ multiserver.servers.append(oneway_server)
+ multiserver.serveForever()
if __name__ == "__main__":
- main()
+ main()