commit
fccea1f70e
145 changed files with 3432 additions and 2674 deletions
@ -0,0 +1,131 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <string> |
||||
|
||||
#include <grpc/grpc_security.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include <grpc++/channel_arguments.h> |
||||
#include <grpc++/config.h> |
||||
#include <grpc++/credentials.h> |
||||
#include "src/cpp/client/channel.h" |
||||
|
||||
namespace grpc { |
||||
|
||||
class SecureCredentials GRPC_FINAL : public Credentials { |
||||
public: |
||||
explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} |
||||
~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } |
||||
grpc_credentials* GetRawCreds() { return c_creds_; } |
||||
|
||||
std::shared_ptr<grpc::ChannelInterface> CreateChannel( |
||||
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE { |
||||
grpc_channel_args channel_args; |
||||
args.SetChannelArgs(&channel_args); |
||||
return std::shared_ptr<ChannelInterface>(new Channel( |
||||
target, |
||||
grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); |
||||
} |
||||
|
||||
SecureCredentials* AsSecureCredentials() { return this; } |
||||
|
||||
private: |
||||
grpc_credentials* const c_creds_; |
||||
}; |
||||
|
||||
namespace { |
||||
std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) { |
||||
return creds == nullptr |
||||
? nullptr |
||||
: std::unique_ptr<Credentials>(new SecureCredentials(creds)); |
||||
} |
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Credentials> GoogleDefaultCredentials() { |
||||
return WrapCredentials(grpc_google_default_credentials_create()); |
||||
} |
||||
|
||||
// Builds SSL Credentials given SSL specific options
|
||||
std::unique_ptr<Credentials> SslCredentials( |
||||
const SslCredentialsOptions& options) { |
||||
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { |
||||
options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; |
||||
|
||||
grpc_credentials* c_creds = grpc_ssl_credentials_create( |
||||
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), |
||||
options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); |
||||
return WrapCredentials(c_creds); |
||||
} |
||||
|
||||
// Builds credentials for use when running in GCE
|
||||
std::unique_ptr<Credentials> ComputeEngineCredentials() { |
||||
return WrapCredentials(grpc_compute_engine_credentials_create()); |
||||
} |
||||
|
||||
// Builds service account credentials.
|
||||
std::unique_ptr<Credentials> ServiceAccountCredentials( |
||||
const grpc::string& json_key, const grpc::string& scope, |
||||
std::chrono::seconds token_lifetime) { |
||||
gpr_timespec lifetime = gpr_time_from_seconds( |
||||
token_lifetime.count() > 0 ? token_lifetime.count() : 0); |
||||
return WrapCredentials(grpc_service_account_credentials_create( |
||||
json_key.c_str(), scope.c_str(), lifetime)); |
||||
} |
||||
|
||||
// Builds IAM credentials.
|
||||
std::unique_ptr<Credentials> IAMCredentials( |
||||
const grpc::string& authorization_token, |
||||
const grpc::string& authority_selector) { |
||||
return WrapCredentials(grpc_iam_credentials_create( |
||||
authorization_token.c_str(), authority_selector.c_str())); |
||||
} |
||||
|
||||
// Combines two credentials objects into a composite credentials.
|
||||
std::unique_ptr<Credentials> CompositeCredentials( |
||||
const std::unique_ptr<Credentials>& creds1, |
||||
const std::unique_ptr<Credentials>& creds2) { |
||||
// Note that we are not saving unique_ptrs to the two credentials
|
||||
// passed in here. This is OK because the underlying C objects (i.e.,
|
||||
// creds1 and creds2) into grpc_composite_credentials_create will see their
|
||||
// refcounts incremented.
|
||||
SecureCredentials* s1 = creds1->AsSecureCredentials(); |
||||
SecureCredentials* s2 = creds2->AsSecureCredentials(); |
||||
if (s1 && s2) { |
||||
return WrapCredentials(grpc_composite_credentials_create( |
||||
s1->GetRawCreds(), s2->GetRawCreds())); |
||||
} |
||||
return nullptr; |
||||
} |
||||
|
||||
} // namespace grpc
|
@ -0,0 +1,71 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/grpc_security.h> |
||||
|
||||
#include <grpc++/server_credentials.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
namespace { |
||||
class SecureServerCredentials GRPC_FINAL : public ServerCredentials { |
||||
public: |
||||
explicit SecureServerCredentials(grpc_server_credentials* creds) : creds_(creds) {} |
||||
~SecureServerCredentials() GRPC_OVERRIDE { |
||||
grpc_server_credentials_release(creds_); |
||||
} |
||||
|
||||
int AddPortToServer(const grpc::string& addr, |
||||
grpc_server* server) GRPC_OVERRIDE { |
||||
return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); |
||||
} |
||||
|
||||
private: |
||||
grpc_server_credentials* const creds_; |
||||
}; |
||||
} // namespace
|
||||
|
||||
std::shared_ptr<ServerCredentials> SslServerCredentials( |
||||
const SslServerCredentialsOptions &options) { |
||||
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs; |
||||
for (const auto &key_cert_pair : options.pem_key_cert_pairs) { |
||||
pem_key_cert_pairs.push_back( |
||||
{key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); |
||||
} |
||||
grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create( |
||||
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), |
||||
&pem_key_cert_pairs[0], pem_key_cert_pairs.size()); |
||||
return std::shared_ptr<ServerCredentials>(new SecureServerCredentials(c_creds)); |
||||
} |
||||
|
||||
} // namespace grpc
|
@ -0,0 +1,407 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Grpc.Core.Internal; |
||||
using Grpc.Core.Utils; |
||||
|
||||
namespace Grpc.Core.Internal |
||||
{ |
||||
/// <summary> |
||||
/// Base for handling both client side and server side calls. |
||||
/// Handles native call lifecycle and provides convenience methods. |
||||
/// </summary> |
||||
internal abstract class AsyncCallBase<TWrite, TRead> |
||||
{ |
||||
readonly Func<TWrite, byte[]> serializer; |
||||
readonly Func<byte[], TRead> deserializer; |
||||
|
||||
protected readonly CompletionCallbackDelegate sendFinishedHandler; |
||||
protected readonly CompletionCallbackDelegate readFinishedHandler; |
||||
protected readonly CompletionCallbackDelegate halfclosedHandler; |
||||
|
||||
protected readonly object myLock = new object(); |
||||
|
||||
protected GCHandle gchandle; |
||||
protected CallSafeHandle call; |
||||
protected bool disposed; |
||||
|
||||
protected bool started; |
||||
protected bool errorOccured; |
||||
protected bool cancelRequested; |
||||
|
||||
protected AsyncCompletionDelegate sendCompletionDelegate; // Completion of a pending send or sendclose if not null. |
||||
protected bool readPending; // True if there is a read in progress. |
||||
protected bool readingDone; |
||||
protected bool halfcloseRequested; |
||||
protected bool halfclosed; |
||||
protected bool finished; // True if close has been received from the peer. |
||||
|
||||
// Streaming reads will be delivered to this observer. For a call that only does unary read it may remain null. |
||||
protected IObserver<TRead> readObserver; |
||||
|
||||
public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer) |
||||
{ |
||||
this.serializer = Preconditions.CheckNotNull(serializer); |
||||
this.deserializer = Preconditions.CheckNotNull(deserializer); |
||||
|
||||
this.sendFinishedHandler = CreateBatchCompletionCallback(HandleSendFinished); |
||||
this.readFinishedHandler = CreateBatchCompletionCallback(HandleReadFinished); |
||||
this.halfclosedHandler = CreateBatchCompletionCallback(HandleHalfclosed); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Requests cancelling the call. |
||||
/// </summary> |
||||
public void Cancel() |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
Preconditions.CheckState(started); |
||||
cancelRequested = true; |
||||
|
||||
if (!disposed) |
||||
{ |
||||
call.Cancel(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Requests cancelling the call with given status. |
||||
/// </summary> |
||||
public void CancelWithStatus(Status status) |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
Preconditions.CheckState(started); |
||||
cancelRequested = true; |
||||
|
||||
if (!disposed) |
||||
{ |
||||
call.CancelWithStatus(status); |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected void InitializeInternal(CallSafeHandle call) |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
// Make sure this object and the delegated held by it will not be garbage collected |
||||
// before we release this handle. |
||||
gchandle = GCHandle.Alloc(this); |
||||
this.call = call; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initiates sending a message. Only once send operation can be active at a time. |
||||
/// completionDelegate is invoked upon completion. |
||||
/// </summary> |
||||
protected void StartSendMessageInternal(TWrite msg, AsyncCompletionDelegate completionDelegate) |
||||
{ |
||||
byte[] payload = UnsafeSerialize(msg); |
||||
|
||||
lock (myLock) |
||||
{ |
||||
Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); |
||||
CheckSendingAllowed(); |
||||
|
||||
call.StartSendMessage(payload, sendFinishedHandler); |
||||
sendCompletionDelegate = completionDelegate; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Requests receiving a next message. |
||||
/// </summary> |
||||
protected void StartReceiveMessage() |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
Preconditions.CheckState(started); |
||||
Preconditions.CheckState(!disposed); |
||||
Preconditions.CheckState(!errorOccured); |
||||
|
||||
Preconditions.CheckState(!readingDone); |
||||
Preconditions.CheckState(!readPending); |
||||
|
||||
call.StartReceiveMessage(readFinishedHandler); |
||||
readPending = true; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Default behavior just completes the read observer, but more sofisticated behavior might be required |
||||
/// by subclasses. |
||||
/// </summary> |
||||
protected virtual void CompleteReadObserver() |
||||
{ |
||||
FireReadObserverOnCompleted(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If there are no more pending actions and no new actions can be started, releases |
||||
/// the underlying native resources. |
||||
/// </summary> |
||||
protected bool ReleaseResourcesIfPossible() |
||||
{ |
||||
if (!disposed && call != null) |
||||
{ |
||||
if (halfclosed && readingDone && finished) |
||||
{ |
||||
ReleaseResources(); |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private void ReleaseResources() |
||||
{ |
||||
if (call != null) |
||||
{ |
||||
call.Dispose(); |
||||
} |
||||
gchandle.Free(); |
||||
disposed = true; |
||||
} |
||||
|
||||
protected void CheckSendingAllowed() |
||||
{ |
||||
Preconditions.CheckState(started); |
||||
Preconditions.CheckState(!disposed); |
||||
Preconditions.CheckState(!errorOccured); |
||||
|
||||
Preconditions.CheckState(!halfcloseRequested, "Already halfclosed."); |
||||
Preconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time"); |
||||
} |
||||
|
||||
protected byte[] UnsafeSerialize(TWrite msg) |
||||
{ |
||||
return serializer(msg); |
||||
} |
||||
|
||||
protected bool TrySerialize(TWrite msg, out byte[] payload) |
||||
{ |
||||
try |
||||
{ |
||||
payload = serializer(msg); |
||||
return true; |
||||
} |
||||
catch(Exception) |
||||
{ |
||||
Console.WriteLine("Exception occured while trying to serialize message"); |
||||
payload = null; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
protected bool TryDeserialize(byte[] payload, out TRead msg) |
||||
{ |
||||
try |
||||
{ |
||||
msg = deserializer(payload); |
||||
return true; |
||||
} |
||||
catch(Exception) |
||||
{ |
||||
Console.WriteLine("Exception occured while trying to deserialize message"); |
||||
msg = default(TRead); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
protected void FireReadObserverOnNext(TRead value) |
||||
{ |
||||
try |
||||
{ |
||||
readObserver.OnNext(value); |
||||
} |
||||
catch(Exception e) |
||||
{ |
||||
Console.WriteLine("Exception occured while invoking readObserver.OnNext: " + e); |
||||
} |
||||
} |
||||
|
||||
protected void FireReadObserverOnCompleted() |
||||
{ |
||||
try |
||||
{ |
||||
readObserver.OnCompleted(); |
||||
} |
||||
catch(Exception e) |
||||
{ |
||||
Console.WriteLine("Exception occured while invoking readObserver.OnCompleted: " + e); |
||||
} |
||||
} |
||||
|
||||
protected void FireReadObserverOnError(Exception error) |
||||
{ |
||||
try |
||||
{ |
||||
readObserver.OnError(error); |
||||
} |
||||
catch(Exception e) |
||||
{ |
||||
Console.WriteLine("Exception occured while invoking readObserver.OnError: " + e); |
||||
} |
||||
} |
||||
|
||||
protected void FireCompletion(AsyncCompletionDelegate completionDelegate, Exception error) |
||||
{ |
||||
try |
||||
{ |
||||
completionDelegate(error); |
||||
} |
||||
catch(Exception e) |
||||
{ |
||||
Console.WriteLine("Exception occured while invoking completion delegate: " + e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Creates completion callback delegate that wraps the batch completion handler in a try catch block to |
||||
/// prevent propagating exceptions accross managed/unmanaged boundary. |
||||
/// </summary> |
||||
protected CompletionCallbackDelegate CreateBatchCompletionCallback(Action<bool, BatchContextSafeHandleNotOwned> handler) |
||||
{ |
||||
return new CompletionCallbackDelegate( (error, batchContextPtr) => { |
||||
try |
||||
{ |
||||
var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr); |
||||
bool wasError = (error != GRPCOpError.GRPC_OP_OK); |
||||
handler(wasError, ctx); |
||||
} |
||||
catch(Exception e) |
||||
{ |
||||
Console.WriteLine("Caught exception in a native handler: " + e); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handles send completion. |
||||
/// </summary> |
||||
private void HandleSendFinished(bool wasError, BatchContextSafeHandleNotOwned ctx) |
||||
{ |
||||
AsyncCompletionDelegate origCompletionDelegate = null; |
||||
lock (myLock) |
||||
{ |
||||
origCompletionDelegate = sendCompletionDelegate; |
||||
sendCompletionDelegate = null; |
||||
|
||||
ReleaseResourcesIfPossible(); |
||||
} |
||||
|
||||
if (wasError) |
||||
{ |
||||
FireCompletion(origCompletionDelegate, new OperationFailedException("Send failed")); |
||||
} |
||||
else |
||||
{ |
||||
FireCompletion(origCompletionDelegate, null); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handles halfclose completion. |
||||
/// </summary> |
||||
private void HandleHalfclosed(bool wasError, BatchContextSafeHandleNotOwned ctx) |
||||
{ |
||||
AsyncCompletionDelegate origCompletionDelegate = null; |
||||
lock (myLock) |
||||
{ |
||||
halfclosed = true; |
||||
origCompletionDelegate = sendCompletionDelegate; |
||||
sendCompletionDelegate = null; |
||||
|
||||
ReleaseResourcesIfPossible(); |
||||
} |
||||
|
||||
if (wasError) |
||||
{ |
||||
FireCompletion(origCompletionDelegate, new OperationFailedException("Halfclose failed")); |
||||
} |
||||
else |
||||
{ |
||||
FireCompletion(origCompletionDelegate, null); |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handles streaming read completion. |
||||
/// </summary> |
||||
private void HandleReadFinished(bool wasError, BatchContextSafeHandleNotOwned ctx) |
||||
{ |
||||
var payload = ctx.GetReceivedMessage(); |
||||
|
||||
lock (myLock) |
||||
{ |
||||
readPending = false; |
||||
if (payload == null) |
||||
{ |
||||
readingDone = true; |
||||
} |
||||
|
||||
ReleaseResourcesIfPossible(); |
||||
} |
||||
|
||||
// TODO: handle the case when error occured... |
||||
|
||||
if (payload != null) |
||||
{ |
||||
// TODO: handle deserialization error |
||||
TRead msg; |
||||
TryDeserialize(payload, out msg); |
||||
|
||||
FireReadObserverOnNext(msg); |
||||
|
||||
// Start a new read. The current one has already been delivered, |
||||
// so correct ordering of reads is assured. |
||||
StartReceiveMessage(); |
||||
} |
||||
else |
||||
{ |
||||
CompleteReadObserver(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,125 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Grpc.Core.Internal; |
||||
using Grpc.Core.Utils; |
||||
|
||||
namespace Grpc.Core.Internal |
||||
{ |
||||
/// <summary> |
||||
/// Handles server side native call lifecycle. |
||||
/// </summary> |
||||
internal class AsyncCallServer<TRequest, TResponse> : AsyncCallBase<TResponse, TRequest> |
||||
{ |
||||
readonly CompletionCallbackDelegate finishedServersideHandler; |
||||
readonly TaskCompletionSource<object> finishedServersideTcs = new TaskCompletionSource<object>(); |
||||
|
||||
public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer) : base(serializer, deserializer) |
||||
{ |
||||
this.finishedServersideHandler = CreateBatchCompletionCallback(HandleFinishedServerside); |
||||
} |
||||
|
||||
public void Initialize(CallSafeHandle call) |
||||
{ |
||||
InitializeInternal(call); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Starts a server side call. Currently, all server side calls are implemented as duplex |
||||
/// streaming call and they are adapted to the appropriate streaming arity. |
||||
/// </summary> |
||||
public Task ServerSideCallAsync(IObserver<TRequest> readObserver) |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
Preconditions.CheckNotNull(call); |
||||
|
||||
started = true; |
||||
this.readObserver = readObserver; |
||||
|
||||
call.StartServerSide(finishedServersideHandler); |
||||
StartReceiveMessage(); |
||||
return finishedServersideTcs.Task; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Sends a streaming response. Only one pending send action is allowed at any given time. |
||||
/// completionDelegate is called when the operation finishes. |
||||
/// </summary> |
||||
public void StartSendMessage(TResponse msg, AsyncCompletionDelegate completionDelegate) |
||||
{ |
||||
StartSendMessageInternal(msg, completionDelegate); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Sends call result status, also indicating server is done with streaming responses. |
||||
/// Only one pending send action is allowed at any given time. |
||||
/// completionDelegate is called when the operation finishes. |
||||
/// </summary> |
||||
public void StartSendStatusFromServer(Status status, AsyncCompletionDelegate completionDelegate) |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); |
||||
CheckSendingAllowed(); |
||||
|
||||
call.StartSendStatusFromServer(status, halfclosedHandler); |
||||
halfcloseRequested = true; |
||||
sendCompletionDelegate = completionDelegate; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handles the server side close completion. |
||||
/// </summary> |
||||
private void HandleFinishedServerside(bool wasError, BatchContextSafeHandleNotOwned ctx) |
||||
{ |
||||
lock (myLock) |
||||
{ |
||||
finished = true; |
||||
|
||||
ReleaseResourcesIfPossible(); |
||||
} |
||||
// TODO: handle error ... |
||||
|
||||
finishedServersideTcs.SetResult(null); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,95 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Grpc.Core.Internal; |
||||
using Grpc.Core.Utils; |
||||
|
||||
namespace Grpc.Core.Internal |
||||
{ |
||||
/// <summary> |
||||
/// If error != null, there's been an error or operation has been cancelled. |
||||
/// </summary> |
||||
internal delegate void AsyncCompletionDelegate(Exception error); |
||||
|
||||
/// <summary> |
||||
/// Helper for transforming AsyncCompletionDelegate into full-fledged Task. |
||||
/// </summary> |
||||
internal class AsyncCompletionTaskSource |
||||
{ |
||||
readonly TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); |
||||
readonly AsyncCompletionDelegate completionDelegate; |
||||
|
||||
public AsyncCompletionTaskSource() |
||||
{ |
||||
completionDelegate = new AsyncCompletionDelegate(HandleCompletion); |
||||
} |
||||
|
||||
public Task Task |
||||
{ |
||||
get |
||||
{ |
||||
return tcs.Task; |
||||
} |
||||
} |
||||
|
||||
public AsyncCompletionDelegate CompletionDelegate |
||||
{ |
||||
get |
||||
{ |
||||
return completionDelegate; |
||||
} |
||||
} |
||||
|
||||
private void HandleCompletion(Exception error) |
||||
{ |
||||
if (error == null) |
||||
{ |
||||
tcs.SetResult(null); |
||||
return; |
||||
} |
||||
if (error is OperationCanceledException) |
||||
{ |
||||
tcs.SetCanceled(); |
||||
return; |
||||
} |
||||
tcs.SetException(error); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,48 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
|
||||
namespace Grpc.Core |
||||
{ |
||||
/// <summary> |
||||
/// Thrown when gRPC operation fails. |
||||
/// </summary> |
||||
public class OperationFailedException : Exception |
||||
{ |
||||
public OperationFailedException(string message) : base(message) |
||||
{ |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,113 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Threading.Tasks; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Concurrent; |
||||
using System.Diagnostics; |
||||
|
||||
namespace Grpc.Core.Utils |
||||
{ |
||||
public static class Preconditions |
||||
{ |
||||
/// <summary> |
||||
/// Throws ArgumentException if condition is false. |
||||
/// </summary> |
||||
public static void CheckArgument(bool condition) |
||||
{ |
||||
if (!condition) |
||||
{ |
||||
throw new ArgumentException(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Throws ArgumentException with given message if condition is false. |
||||
/// </summary> |
||||
public static void CheckArgument(bool condition, string errorMessage) |
||||
{ |
||||
if (!condition) |
||||
{ |
||||
throw new ArgumentException(errorMessage); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Throws NullReferenceException if reference is null. |
||||
/// </summary> |
||||
public static T CheckNotNull<T> (T reference) |
||||
{ |
||||
if (reference == null) |
||||
{ |
||||
throw new NullReferenceException(); |
||||
} |
||||
return reference; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Throws NullReferenceException with given message if reference is null. |
||||
/// </summary> |
||||
public static T CheckNotNull<T> (T reference, string errorMessage) |
||||
{ |
||||
if (reference == null) |
||||
{ |
||||
throw new NullReferenceException(errorMessage); |
||||
} |
||||
return reference; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Throws InvalidOperationException if condition is false. |
||||
/// </summary> |
||||
public static void CheckState(bool condition) |
||||
{ |
||||
if (!condition) |
||||
{ |
||||
throw new InvalidOperationException(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Throws InvalidOperationException with given message if condition is false. |
||||
/// </summary> |
||||
public static void CheckState(bool condition, string errorMessage) |
||||
{ |
||||
if (!condition) |
||||
{ |
||||
throw new InvalidOperationException(errorMessage); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,94 @@ |
||||
/* |
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var assert = require('assert'); |
||||
var grpc = require('bindings')('grpc.node'); |
||||
|
||||
describe('server', function() { |
||||
describe('constructor', function() { |
||||
it('should work with no arguments', function() { |
||||
assert.doesNotThrow(function() { |
||||
new grpc.Server(); |
||||
}); |
||||
}); |
||||
it('should work with an empty list argument', function() { |
||||
assert.doesNotThrow(function() { |
||||
new grpc.Server([]); |
||||
}); |
||||
}); |
||||
}); |
||||
describe('addHttp2Port', function() { |
||||
var server; |
||||
before(function() { |
||||
server = new grpc.Server(); |
||||
}); |
||||
it('should bind to an unused port', function() { |
||||
var port; |
||||
assert.doesNotThrow(function() { |
||||
port = server.addHttp2Port('0.0.0.0:0'); |
||||
}); |
||||
assert(port > 0); |
||||
}); |
||||
}); |
||||
describe('addSecureHttp2Port', function() { |
||||
var server; |
||||
before(function() { |
||||
server = new grpc.Server(); |
||||
}); |
||||
it('should bind to an unused port with fake credentials', function() { |
||||
var port; |
||||
var creds = grpc.ServerCredentials.createFake(); |
||||
assert.doesNotThrow(function() { |
||||
port = server.addSecureHttp2Port('0.0.0.0:0', creds); |
||||
}); |
||||
assert(port > 0); |
||||
}); |
||||
}); |
||||
describe('listen', function() { |
||||
var server; |
||||
before(function() { |
||||
server = new grpc.Server(); |
||||
server.addHttp2Port('0.0.0.0:0'); |
||||
}); |
||||
after(function() { |
||||
server.shutdown(); |
||||
}); |
||||
it('should listen without error', function() { |
||||
assert.doesNotThrow(function() { |
||||
server.start(); |
||||
}); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,56 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
"""Insecure client-server interoperability as a unit test.""" |
||||
|
||||
import unittest |
||||
|
||||
from grpc.early_adopter import implementations |
||||
|
||||
from interop import _interop_test_case |
||||
from interop import methods |
||||
|
||||
|
||||
class InsecureInteropTest( |
||||
_interop_test_case.InteropTestCase, |
||||
unittest.TestCase): |
||||
|
||||
def setUp(self): |
||||
self.server = implementations.insecure_server(methods.SERVER_METHODS, 0) |
||||
self.server.start() |
||||
port = self.server.port() |
||||
self.stub = implementations.insecure_stub( |
||||
methods.CLIENT_METHODS, 'localhost', port) |
||||
|
||||
def tearDown(self): |
||||
self.server.stop() |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
unittest.main() |
@ -0,0 +1,55 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
"""Common code for unit tests of the interoperability test code.""" |
||||
|
||||
from interop import methods |
||||
|
||||
|
||||
class InteropTestCase(object): |
||||
"""Unit test methods. |
||||
|
||||
This class must be mixed in with unittest.TestCase and a class that defines |
||||
setUp and tearDown methods that manage a stub attribute. |
||||
""" |
||||
|
||||
def testEmptyUnary(self): |
||||
methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub) |
||||
|
||||
def testLargeUnary(self): |
||||
methods.TestCase.LARGE_UNARY.test_interoperability(self.stub) |
||||
|
||||
def testServerStreaming(self): |
||||
methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub) |
||||
|
||||
def testClientStreaming(self): |
||||
methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub) |
||||
|
||||
def testPingPong(self): |
||||
methods.TestCase.PING_PONG.test_interoperability(self.stub) |
@ -0,0 +1,63 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
"""Secure client-server interoperability as a unit test.""" |
||||
|
||||
import unittest |
||||
|
||||
from grpc.early_adopter import implementations |
||||
|
||||
from interop import _interop_test_case |
||||
from interop import methods |
||||
from interop import resources |
||||
|
||||
_SERVER_HOST_OVERRIDE = 'foo.test.google.fr' |
||||
|
||||
|
||||
class SecureInteropTest( |
||||
_interop_test_case.InteropTestCase, |
||||
unittest.TestCase): |
||||
|
||||
def setUp(self): |
||||
self.server = implementations.secure_server( |
||||
methods.SERVER_METHODS, 0, resources.private_key(), |
||||
resources.certificate_chain()) |
||||
self.server.start() |
||||
port = self.server.port() |
||||
self.stub = implementations.secure_stub( |
||||
methods.CLIENT_METHODS, 'localhost', port, |
||||
resources.test_root_certificates(), None, None, |
||||
server_host_override=_SERVER_HOST_OVERRIDE) |
||||
|
||||
def tearDown(self): |
||||
self.server.stop() |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
unittest.main() |
@ -1,179 +0,0 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
"""Utilities for assembling RPC framework values.""" |
||||
|
||||
import collections |
||||
|
||||
from grpc.framework.assembly import interfaces |
||||
from grpc.framework.common import cardinality |
||||
from grpc.framework.common import style |
||||
from grpc.framework.face import interfaces as face_interfaces |
||||
from grpc.framework.foundation import stream |
||||
|
||||
|
||||
class _MethodImplementation( |
||||
interfaces.MethodImplementation, |
||||
collections.namedtuple( |
||||
'_MethodImplementation', |
||||
['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline', |
||||
'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event', |
||||
'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])): |
||||
pass |
||||
|
||||
|
||||
def unary_unary_inline(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-unary RPC method as a callable value |
||||
that takes a request value and a face_interfaces.RpcContext object and |
||||
returns a response value. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior, |
||||
None, None, None, None, None, None, None) |
||||
|
||||
|
||||
def unary_stream_inline(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-stream RPC method as a callable |
||||
value that takes a request value and a face_interfaces.RpcContext object |
||||
and returns an iterator of response values. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None, |
||||
behavior, None, None, None, None, None, None) |
||||
|
||||
|
||||
def stream_unary_inline(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-unary RPC method as a callable |
||||
value that takes an iterator of request values and a |
||||
face_interfaces.RpcContext object and returns a response value. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None, |
||||
behavior, None, None, None, None, None) |
||||
|
||||
|
||||
def stream_stream_inline(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-stream RPC method as a callable |
||||
value that takes an iterator of request values and a |
||||
face_interfaces.RpcContext object and returns an iterator of response |
||||
values. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None, |
||||
None, behavior, None, None, None, None) |
||||
|
||||
|
||||
def unary_unary_event(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-unary RPC method as a callable |
||||
value that takes a request value, a response callback to which to pass |
||||
the response value of the RPC, and a face_interfaces.RpcContext. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None, |
||||
None, None, behavior, None, None, None) |
||||
|
||||
|
||||
def unary_stream_event(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-stream RPC method as a callable |
||||
value that takes a request value, a stream.Consumer to which to pass the |
||||
the response values of the RPC, and a face_interfaces.RpcContext. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None, |
||||
None, None, None, behavior, None, None) |
||||
|
||||
|
||||
def stream_unary_event(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-unary RPC method as a callable |
||||
value that takes a response callback to which to pass the response value |
||||
of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer |
||||
to which the request values of the RPC should be passed. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None, |
||||
None, None, None, None, behavior, None) |
||||
|
||||
|
||||
def stream_stream_event(behavior): |
||||
"""Creates an interfaces.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-stream RPC method as a callable |
||||
value that takes a stream.Consumer to which to pass the response values |
||||
of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer |
||||
to which the request values of the RPC should be passed. |
||||
|
||||
Returns: |
||||
An interfaces.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None, |
||||
None, None, None, None, None, behavior) |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue