em-synchrony-moped 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # EM-Synchrony-Moped
2
+
3
+ EM-Synchrony-Moped is a [Moped](https://github.com/mongoid/mongoid) driver patch for [EM-Synchrony](http://github.com/igrigorik/em-synchrony). Moped is the MongoDB driver for the [Mongoid](http://github.com/mongoid/mongoid).
4
+
5
+ * Supports SSL connections
6
+
7
+ ## Usage
8
+
9
+ In order to use this driver in an EM-Synchrony environment, simply include the driver.
10
+
11
+ ```ruby
12
+ require "em-synchrony/moped"
13
+
14
+ ```
15
+
16
+ To use SSL:
17
+ ```ruby
18
+ require "em-synchrony/moped"
19
+
20
+ ```
21
+
22
+
23
+ # License
24
+
25
+ The MIT License - Copyright (c) 2013 Adam Lebsack
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ task :default => [:spec]
8
+ task :test => [:spec]
9
+
10
+ desc "Run all RSpec tests"
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+
14
+ rescue LoadError
15
+ # silent failure for when rspec is not installed (production mode)
16
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'em-synchrony-moped'
5
+ s.version = "0.9.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Adam Lebsack"]
9
+ s.email = ["alebsack@gmail.com"]
10
+
11
+ s.summary = %q{Moped driver for EM-Synchrony}
12
+ s.description = %q{EM-Synchrony-Moped is a Moped driver patch for EM-Synchtony, allowing your asynchronous application use non-blocking connections to MongoDB. Moped is the MongoDB driver for the Mongoid ORM.}
13
+ s.email = %q{alebsack@gmail.com}
14
+
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency 'eventmachine'
22
+ s.add_runtime_dependency 'em-synchrony', '~> 1.0'
23
+ s.add_runtime_dependency 'moped', '~> 1.4.5'
24
+
25
+ s.add_development_dependency 'rspec', '~> 2.12.0'
26
+
27
+ end
@@ -0,0 +1,118 @@
1
+ require "moped/connection"
2
+
3
+ silence_warnings {
4
+
5
+ module Moped
6
+ class Cluster
7
+ def sleep(seconds)
8
+ EM::Synchrony.sleep(seconds)
9
+ end
10
+ end
11
+
12
+ class Connection
13
+ def connect
14
+ @sock = if !!options[:ssl]
15
+ Sockets::SSL.connect(host, port, timeout, options)
16
+ else
17
+ Sockets::TCP.connect(host, port, timeout, options)
18
+ end
19
+ end
20
+ end
21
+
22
+ Sockets.send(:remove_const, :TCP)
23
+ Sockets.send(:remove_const, :SSL)
24
+ module Sockets
25
+ module Connectable
26
+ attr_accessor :options
27
+
28
+ def alive?
29
+ !closed?
30
+ end
31
+
32
+ module ClassMethods
33
+
34
+ def connect(host, port, timeout, options={})
35
+ socket = EM.connect(host, port, self) do |c|
36
+ c.pending_connect_timeout = timeout
37
+ c.comm_inactivity_timeout = timeout
38
+ c.options = options.merge(:host => host)
39
+ end
40
+ # In TCPSocket, new against a closed port raises Errno::ECONNREFUSED.
41
+ # In EM, connect against a closed port result in a call to unbind with
42
+ # a reason param of Errno::ECONNREFUSED as a class, not an instance.
43
+ unless socket.sync(:in) # wait for connection
44
+ raise socket.unbind_reason.new if socket.unbind_reason.is_a? Class
45
+ raise SocketError, socket.unbind_reason
46
+ end
47
+ socket
48
+
49
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, IOError => error
50
+ raise Errors::ConnectionFailure, "#{host}:#{port}: #{error.class.name} (#{error.errno}): #{error.message}"
51
+ rescue SocketError => error
52
+ raise Errors::ConnectionFailure, "#{host}:#{port}: #{error.class.name}: #{error.message}"
53
+ rescue OpenSSL::SSL::SSLError => error
54
+ raise Errors::ConnectionFailure, "#{host}:#{port}: #{error.class.name} (#{error.errno}): #{error.message}"
55
+ end
56
+
57
+
58
+ end
59
+ end
60
+
61
+ class TCP < EventMachine::Synchrony::TCPSocket
62
+ include Connectable
63
+ end
64
+
65
+ class SSL < EventMachine::Synchrony::TCPSocket
66
+ include Connectable
67
+
68
+ def connection_completed
69
+ @verified = false
70
+ if @options[:ssl].is_a?(Hash)
71
+ start_tls(@options[:ssl])
72
+ else
73
+ start_tls
74
+ end
75
+ end
76
+
77
+ def ssl_verify_peer(pem)
78
+ unless cert_store = @options[:ssl][:cert_store]
79
+ cert_store = OpenSSL::X509::Store.new
80
+ cert_store.add_file(@options[:ssl][:verify_cert])
81
+ end
82
+
83
+ if cert = OpenSSL::X509::Certificate.new(pem) rescue nil
84
+ if cert_store.verify(cert)
85
+
86
+ cert.extensions.each do |e|
87
+ if e.oid == 'basicConstraints' && e.value == 'CA:TRUE'
88
+ return true
89
+ end
90
+ end
91
+
92
+ host = @options[:ssl][:verify_host] || @options[:host]
93
+ if OpenSSL::SSL.verify_certificate_identity(cert, host)
94
+ @verified = true
95
+ return true
96
+ end
97
+ end
98
+ end
99
+
100
+ true
101
+ rescue => e
102
+ unbind "Failed to verify SSL certificate of peer"
103
+ false
104
+ end
105
+
106
+ def ssl_handshake_completed
107
+ if @options[:ssl][:verify_peer] && !@verified
108
+ unbind "Failed to verify SSL certificate of peer"
109
+ else
110
+ @opening = false
111
+ @in_req.succeed self
112
+ end
113
+ end
114
+
115
+ end
116
+ end
117
+ end
118
+ }
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+
3
+ require 'moped'
4
+ require 'em-synchrony/moped'
5
+
6
+ describe "em-synchrony/moped" do
7
+
8
+ def new_node(options={})
9
+ options.merge!(:timeout => 1)
10
+ host = options.delete(:host) || 'localhost'
11
+ Moped::Node.new("#{host}:#{FakeMongodHelper::BASE_PORT}", options)
12
+ end
13
+
14
+ context "without ssl" do
15
+
16
+ it "should connect" do
17
+ EventMachine.synchrony do
18
+ start_mongod
19
+
20
+ node = new_node
21
+ node.refresh
22
+ node.should be_primary
23
+ EM.stop
24
+ end
25
+ end
26
+
27
+
28
+ it "should raise a connection error on timeout" do
29
+ lambda {
30
+ EventMachine.synchrony do
31
+ start_mongod
32
+
33
+ # google.com seems timeout for my tests...
34
+ node = new_node(:host => "google.com")
35
+ node.refresh
36
+
37
+ EM.stop
38
+ end
39
+ }.should raise_exception(Moped::Errors::ConnectionFailure, /ETIMEDOUT/)
40
+ end
41
+
42
+ it "should raise a connection error on connection refused" do
43
+ lambda {
44
+ EventMachine.synchrony do
45
+ new_node.refresh
46
+ EM.stop
47
+ end
48
+ }.should raise_exception(Moped::Errors::ConnectionFailure, /ECONNREFUSED/)
49
+ end
50
+ end
51
+
52
+ context "without ssl" do
53
+ it "should connect and not verify peer" do
54
+ EventMachine.synchrony do
55
+ start_mongod(
56
+ :ssl => {
57
+ :private_key_file => "#{SSL_DIR}/server.key",
58
+ :cert_chain_file => "#{SSL_DIR}/server.crt",
59
+ :verify_peer => false
60
+ }
61
+ )
62
+
63
+ node = new_node(:ssl => {:verify_peer => false})
64
+ node.refresh
65
+ node.should be_primary
66
+
67
+ EM.stop
68
+ end
69
+ end
70
+
71
+ it "should connect and verify peer" do
72
+ EventMachine.synchrony do
73
+ start_mongod(
74
+ :ssl => {
75
+ :private_key_file => "#{SSL_DIR}/server.key",
76
+ :cert_chain_file => "#{SSL_DIR}/server.crt",
77
+ :verify_peer => false
78
+ }
79
+ )
80
+
81
+ node = new_node(:ssl => {
82
+ :verify_peer => true,
83
+ :verify_cert => "#{SSL_DIR}/ca_cert.pem",
84
+ :verify_host => "localhost"
85
+ })
86
+ node.refresh
87
+ node.should be_primary
88
+
89
+ EM.stop
90
+ end
91
+ end
92
+
93
+
94
+ it "should connect and fail to verify peer" do
95
+ lambda {
96
+
97
+ EventMachine.synchrony do
98
+ start_mongod(
99
+ :ssl => {
100
+ :private_key_file => "#{SSL_DIR}/untrusted.key",
101
+ :cert_chain_file => "#{SSL_DIR}/untrusted.crt",
102
+ :verify_peer => false
103
+ }
104
+ )
105
+
106
+ node = new_node(:ssl => {
107
+ :verify_peer => true,
108
+ :verify_cert => "#{SSL_DIR}/ca_cert.pem",
109
+ :verify_host => "localhost"
110
+ })
111
+
112
+ node.refresh
113
+ node.should be_primary
114
+
115
+ EM.stop
116
+ end
117
+ }.should raise_exception(Moped::Errors::ConnectionFailure, /Failed to verify SSL certificate of peer/)
118
+ end
119
+
120
+
121
+ end
122
+
123
+
124
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ require "rspec"
5
+
6
+ require 'em-synchrony'
7
+
8
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |f| require f }
9
+
10
+ SSL_DIR = File.expand_path("../ssl", __FILE__)
11
+
12
+ RSpec.configure do |config|
13
+
14
+
15
+ end
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDODCCAiCgAwIBAgIBATALBgkqhkiG9w0BAQswQjEQMA4GA1UEAwwHVGVzdCBD
3
+ QTELMAkGA1UEBhMCVVMxITAfBgkqhkiG9w0BCQEWEmFsZWJzYWNrQGdtYWlsLmNv
4
+ bTAeFw0xMzA0MjgyMjAwMzBaFw0yMzA0MjYyMjAwMzBaMEIxEDAOBgNVBAMMB1Rl
5
+ c3QgQ0ExCzAJBgNVBAYTAlVTMSEwHwYJKoZIhvcNAQkBFhJhbGVic2Fja0BnbWFp
6
+ bC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFWoHcCntUnNpD
7
+ qBSZqx5LyrvIHqXOo1a/vKP6OE2uBRVGA8M2V8OPJfFJA6rvNMwU9Hd6Ft7znN+G
8
+ Nrtoagl4w2Fr+DoaUQdjUbg8T5e1kAhcOXrqzQMv70ig+hispU2JgbX7ixHu0vC8
9
+ PEDPLWmrb8fSWnF8APhamFOL5efEzL0vI1HlVfTKN52Twc5obHzmRXyxER13dQit
10
+ HBrxB69uN7M9deozmpu34/Pjw7OMBQTAs+r7nWTvX8rQaf15PXkwYb+PQrWZp8bd
11
+ HKpqr/R9E4k+J9QA6CLNMXeeZwoJ5TRz8dHXHCS2xctJnC84+Q92EnM2i8cwWA95
12
+ YpIPI/o9AgMBAAGjOzA5MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgKE
13
+ MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBm8A8M
14
+ 49WMsWyowvao7psT/b1qe41uI7IfqCx8Mjh4+TRyk5/+zZtME+GWM0iRt0JMGomc
15
+ lhKjM9Q7S7kuE6oaMvwhFrrjtdMGlB+uQRG05AQaeDifYKsCACg+/1lRCbavGEvm
16
+ GqNSG5/jLoPE9ekuDsanz1ZxcfBTd1qhYfI9TW+7rpbpY+nGhkNpURA4WjeKSq7X
17
+ I2xTQhbSSiQYNwvSOEH8V2PP+6F2IEv//wCu7S5r/gPWp/B7JocvFK2oprAqgvm+
18
+ ZMkrYM4r2Mi96KUtmlPvNF4u7F3/FVPtoNmvw9nqM7ODIrKudNf5OJRC6C4FwpV4
19
+ 5Mud2Jw9mvbcZzNT
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDRTCCAi2gAwIBAgIBAjALBgkqhkiG9w0BAQswQjEQMA4GA1UEAwwHVGVzdCBD
3
+ QTELMAkGA1UEBhMCVVMxITAfBgkqhkiG9w0BCQEWEmFsZWJzYWNrQGdtYWlsLmNv
4
+ bTAeFw0xMzA0MjgyMjA2MjVaFw0yMzA0MjYyMjA2MjVaMEQxEjAQBgNVBAMMCWxv
5
+ Y2FsaG9zdDELMAkGA1UEBhMCVVMxITAfBgkqhkiG9w0BCQEWEmFsZWJzYWNrQGdt
6
+ YWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOrW1F5LzzR6
7
+ L+UnzTamxPZIIACBlyymkPA8TVlFKSu1tITSzAyHiNoP6y3tig1l+R1LxT+eY26Z
8
+ eAgwbXznvY1dJfKo7sH38IgL2cNsC3DCe/b1Ue15H5SLa+uDHTXUaybfve/dwCXO
9
+ 9oq0yHhrC9+4zppnLWXQekemW35WtRAX1Rds0pZNwxfanj8wy7+qfGIUPqQ11JiV
10
+ lJ1jx2Th+3IxvPFmoNZ5HFTgudNK76hzYjVq7SZb0fH/YwGt1uVR2qI7NW1GooCm
11
+ lK46SGAT3VDQqyNrXmNk5CSoID+4GqFuruLEK/KFgE6U30/8haWPrVQ5cNp/EoXA
12
+ Wp/q+Q/dSnkCAwEAAaNGMEQwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoG
13
+ CCsGAQUFBwMBMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0B
14
+ AQsFAAOCAQEAnm7sxj9bYLLa2t5aLQU3drUKX8FaEcA2TUTWFNvSt7tnLhL+5tVO
15
+ KGN8Xh9q97MWE3jSaJwaZvV+dKp1coH6IxS7jiSeGcLlyLdvW8qoou11LWSR2W4a
16
+ V71LaBgBkaLDupFLGrC9OKuJH2TfV0lII4Rp4w9OQNyPGDd1QTd57JV1IzvByarQ
17
+ X8bSI3VKp2mSzw5z75+zfjC0tjwuJ2uPNEhcrWE1Q46gxH77ucbfqfm2kSr4JXVT
18
+ f8U9R3ee/ReQuk94dC13/lPyj+RMBvgtGoozQR5dG74ZNiG3YTEcl9JmFTCaoM3/
19
+ qV/886MaDQ2weg/1+y4RoZipssK7wBnGtg==
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,31 @@
1
+ Bag Attributes
2
+ friendlyName: localhost
3
+ localKeyID: 15 89 76 85 F8 5E 3F E6 0F B0 4D 0B 06 A9 90 39 1B 32 8A A0
4
+ Key Attributes: <No Attributes>
5
+ -----BEGIN RSA PRIVATE KEY-----
6
+ MIIEpAIBAAKCAQEA6tbUXkvPNHov5SfNNqbE9kggAIGXLKaQ8DxNWUUpK7W0hNLM
7
+ DIeI2g/rLe2KDWX5HUvFP55jbpl4CDBtfOe9jV0l8qjuwffwiAvZw2wLcMJ79vVR
8
+ 7XkflItr64MdNdRrJt+9793AJc72irTIeGsL37jOmmctZdB6R6Zbfla1EBfVF2zS
9
+ lk3DF9qePzDLv6p8YhQ+pDXUmJWUnWPHZOH7cjG88Wag1nkcVOC500rvqHNiNWrt
10
+ JlvR8f9jAa3W5VHaojs1bUaigKaUrjpIYBPdUNCrI2teY2TkJKggP7gaoW6u4sQr
11
+ 8oWATpTfT/yFpY+tVDlw2n8ShcBan+r5D91KeQIDAQABAoIBACL5G2dvoswN5lQa
12
+ OVWKQIrs8tcgdYMQy0T7tgk1Y4w+40NkoT68cIUJGd0dIxIbvZ2/SwDOdcBi2p1d
13
+ mPChEnmbBau9vNDmO8wG98dCr/F7BTsiDbFv+GQG32uTeyYpHEwNxhuSyqrWx6Cg
14
+ i7pjNsF6pEoaU4h2I7/H5phKEWzz1p+XWutIhww/Z2LcH3Pfp0sJGx5jxQW27zcK
15
+ oqq4F4hsa9otZp4UjTNYM3QtBHRpVofq1RECfDHbX2cNOK37CdgI68X5ssZr9b1b
16
+ ercZylqR6rSHWWqE5+CIN3Vvw/fttJazsvxs+zagJXV4eppeGzW75IPfHTDbLB6v
17
+ lefd0AECgYEA94Zd4xdGScIbGYYUYh0WHGxtf2B2pGruv8cLjsVtLNcWaUP9HiJb
18
+ lp4h5rR+lBn5VFPz3OJiEE5UL3xNhEZ7Sh4hiuQGFlsxmYvUMbbbJz8q89dVpmey
19
+ pCtseslfuglcYYxSW/PA9JjLyTDFc7hdndhUPAaFfr0ucpsPxjEPgBECgYEA8uFE
20
+ zCyu3KwIBsMXUN/gCufKrXEZv3UaHKeArLtKx+CrKYl/UAqxylU9YymyiAEa69q2
21
+ 7s0CpJFsoxcXToyx2QnnNKMg168kgS9ga8lrCKFF5HPmWYIJDyYirRPz1DjDE06s
22
+ T/3t5JYDGpdLocynALHYxFyxXaWEjl7HWosxC+kCgYEA5kxuLkwJabbf3++QJ3lI
23
+ iUmY11q5CGE1odlgN4YY/g9hGq/XYaI19P1MLYrh+onwITW7P1iiROmcClJtDRVG
24
+ wL8oFkHyJ/rROzuOQnMPlISBQj6nwhvZakW8uMGD/2OWQGx+dG9mqC1B7f8it3hi
25
+ IeqU9QRcUH9UJ+19z7j14wECgYEA77FbOPhb9ZGdNjcwenMGYxzPy41TsLv7cg3o
26
+ kg8gRNO3d32ndDGpthmbRJKxC0Gz9NFbOZ5/HjQad3VhXfbByYTZdPwMfG7vYsKD
27
+ sLwNcm3eURAEY49OK3IiRJbtSiJeel5o9WSPcsiM9aAcVuhmY+wgFeG4dMfVYr+s
28
+ k/HMDIkCgYAf++B1I76Z6XdMt29wOP6bRk+oSTh/9bJ8KSD8PAq7DYdBAZRPqw72
29
+ cvx+iGbxcA2Erzag0mseOJkyEJmd8UypjtE/uw1VetjS0iBkKqRetBURTHDNt6Ef
30
+ Qv4Nr9OBhlcGKe8hVQ6ArN4JJk8pJ1PE7t2aCWds891ooN7dcsTKSw==
31
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,25 @@
1
+ Bag Attributes
2
+ friendlyName: localhost
3
+ localKeyID: 47 6A C5 CA E0 0D 13 B6 6B 84 F0 20 18 E9 F7 40 00 E7 EC E9
4
+ subject=/CN=localhost/C=US/emailAddress=alebsack@gmail.com
5
+ issuer=/CN=localhost/C=US/emailAddress=alebsack@gmail.com
6
+ -----BEGIN CERTIFICATE-----
7
+ MIIDRzCCAi+gAwIBAgIBATALBgkqhkiG9w0BAQswRDESMBAGA1UEAwwJbG9jYWxo
8
+ b3N0MQswCQYDVQQGEwJVUzEhMB8GCSqGSIb3DQEJARYSYWxlYnNhY2tAZ21haWwu
9
+ Y29tMB4XDTEzMDQyODIyMzQyOFoXDTIzMDQyNjIyMzQyOFowRDESMBAGA1UEAwwJ
10
+ bG9jYWxob3N0MQswCQYDVQQGEwJVUzEhMB8GCSqGSIb3DQEJARYSYWxlYnNhY2tA
11
+ Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvErl6uVq
12
+ op8gvmABuF/3MaLnqBqZEZ45okxM7XPw9zeJeVNvJ7+19rhV0tH44FbRVhOtAB/+
13
+ 1fbEa5DxGTfwWPEMDLEy8DIfXU513xPzCYU9AUSYOGiDDMKaoWKXC2HjjWXtcZMI
14
+ eZ5QG17/TWy4ElkrbxS3opROPcNQLrs810+4uvwOWibFEvHCGNCGnMm94Df2LqU+
15
+ y1s9Pj5FMo35kMYeJMWeLXmA8KCac2rOpBYUPgyVfXsjBgiEZFls8lBqpI4tOztQ
16
+ ZFyhqRfyqpdQ8IMHIELx39+9ydF85eYAb+bGgy8L1w9DZxAPc9Hcujctnd+F4KZi
17
+ qjA1oAwJOTOmrQIDAQABo0YwRDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAww
18
+ CgYIKwYBBQUHAwEwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3
19
+ DQEBCwUAA4IBAQC7TWaKJFnIpaugXkyHWdMvzd9A/KbegOXzN107FgQ/7oyEFUL9
20
+ Mss3MN2lfnRy5WDFLkIWNivKoTBVEJ1b8cHp4CJmA8IcsFSvJw308H9MZoxhyRQ0
21
+ Ud4ezhXxmzKtwbwCaKmGzx63DtpsdC/uXPCYix4M2CvXmvUKbzSIBR3hD9UL4W9k
22
+ Rpe5tCRYJQHATlrW4e4W8Xg4+bszDb29LHCl8e8dAazmMl94j91BkmFBwodrLwVm
23
+ 5ss8SRpNxkGIX1VeL140sWlMGg9Cqk+Fj8zaeTUB85YYMkNF7RNolaGumMv0rmou
24
+ T6kYq7wNK/xm0P9WhSosvH+n/Xx3y/aalwgr
25
+ -----END CERTIFICATE-----
@@ -0,0 +1,31 @@
1
+ Bag Attributes
2
+ friendlyName: localhost
3
+ localKeyID: 47 6A C5 CA E0 0D 13 B6 6B 84 F0 20 18 E9 F7 40 00 E7 EC E9
4
+ Key Attributes: <No Attributes>
5
+ -----BEGIN RSA PRIVATE KEY-----
6
+ MIIEogIBAAKCAQEAvErl6uVqop8gvmABuF/3MaLnqBqZEZ45okxM7XPw9zeJeVNv
7
+ J7+19rhV0tH44FbRVhOtAB/+1fbEa5DxGTfwWPEMDLEy8DIfXU513xPzCYU9AUSY
8
+ OGiDDMKaoWKXC2HjjWXtcZMIeZ5QG17/TWy4ElkrbxS3opROPcNQLrs810+4uvwO
9
+ WibFEvHCGNCGnMm94Df2LqU+y1s9Pj5FMo35kMYeJMWeLXmA8KCac2rOpBYUPgyV
10
+ fXsjBgiEZFls8lBqpI4tOztQZFyhqRfyqpdQ8IMHIELx39+9ydF85eYAb+bGgy8L
11
+ 1w9DZxAPc9Hcujctnd+F4KZiqjA1oAwJOTOmrQIDAQABAoIBAGrg2MEMmArW6G8n
12
+ b9KIJng2T+hLsLcfaPeG9+OQ/CZXj+EeSun1GASDfbO9G9e7b/e8E2cOwkgRWkz0
13
+ aOY3qmXR7VUHADL3QHZmIuININc2mfouRXk/WaPUkpEotTPwzIlmYfEl1Jm0EyR2
14
+ N9Rq8dD4bH8Q82uFYyQLyWe9QDu2O5Hw+gwwjt3t2buOKX+pzymqH8LpKNlTBTol
15
+ 1qG1xp3lZKU7QmNOsznBSSdRV13WK3b+tD+iFSVrsQIX0r3Rh4UVw4QAqyT/8tjY
16
+ Aqb8qv9ccOdU2mKGSEhe0imqJcMBL/Ksh4e+tP0m8eJF/v6QpuqJw56iJ9kzsfY3
17
+ 1AH7QgECgYEA3hxQ9vgA9F4otI7jA/eq+m8D/Ecx2IKZRsOfZvA6J0a4KqXe/auN
18
+ gH4vjMJnTgcWVOheF8WctUf+F89f9Zh0xus6wBJrD6ichWAYUGzFafvpFSe0yNhW
19
+ UIvEhe5UYQp7pQMj4Oi9/PFVQT/zKroOZWY3Y37mkeIzhyEFdpLJ7ikCgYEA2QWk
20
+ gzK6fpOOM+bN3+vJU/1OVk4CdVoSrnz3f9hRj96BxEvr+EXn4f/J4+bItsq16U4f
21
+ 0xAhq+bGVV1PNOrXFqFzhMPtG14xW20mM89/MqBtke5ixB7D0cei29J87SbUX5MB
22
+ oNOg58vAbXb7NFYn3Q+SrQ89LvSASxxpfTjAPOUCgYAb8IvuxTu5ga61J9Q+x4Tm
23
+ g9iIf5wxlBwb3rfKhyWJk0fPdZYbat0d8MGif0HnetTAUYqkiuMvmqLH8/oqNsdZ
24
+ znVRe/+jtJ4b2P61/zjGID4tvxTqvuv8rdhG0LgkjOEI3OBChoR/sQv8bUL1ePoe
25
+ n0EQbwIqD75TnT/GrqhgIQKBgHNJsxZbWYUqX82km9OLj31FwFrKwDWVLv1wt447
26
+ 3UA/ZNJhvq46fK+rUZX3IMMyNqcE8JUQKcMHKm9ozU4AP1jvVc2+w3PZewDln/jA
27
+ DwNXBD4U1HT5Hu+PTS3XyLO2//TxxFiqc/0PWV8NaO9poW2m+zViNg9+pbTBGC0E
28
+ e+MdAoGAeLHx2ftPjj2+/6Zu/p4jzMcMDJurVJLWaHpaSfBAxggMKOHeXeaLCoGd
29
+ mcei57mVOK1udZTnjtFRDLz198pwk1ht2DzzjDSHYQDuOMAekeY0+MfbFzMGha5c
30
+ cUtmdCGOBYbbGnB3oqv6XNSY6cM8EvnVP/VV67fSoxy+DV8La/g=
31
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,142 @@
1
+ require 'eventmachine'
2
+
3
+ require 'moped/protocol/message'
4
+ module Moped
5
+ module Protocol
6
+
7
+ # This patch is so we can parse a query as a server
8
+ module Message
9
+ module ClassMethods
10
+
11
+ alias_method :_old_cstring, :cstring
12
+ def cstring(name)
13
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
+ def deserialize_#{name}(buffer)
15
+ str = ''
16
+ while c = buffer.getc
17
+ break if c == '\0'
18
+ str << c
19
+ end
20
+ self.#{name} = str
21
+ end
22
+ RUBY
23
+ _old_cstring(name)
24
+ end
25
+
26
+ alias_method :_old_document, :document
27
+ def document(name, options = {})
28
+ if options[:optional]
29
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
30
+ def deserialize_#{name}(buffer)
31
+ # noop for now
32
+ end
33
+ RUBY
34
+ else
35
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
36
+ def deserialize_#{name}(buffer)
37
+ self.#{name} = BSON::Document.deserialize(buffer)
38
+ end
39
+ RUBY
40
+ end
41
+ _old_document(name, options)
42
+ end
43
+ end
44
+ end
45
+
46
+ # now that the class DSL is patched, load the message classes we need to patch further
47
+
48
+ # This patch is so we can parse a query as a server
49
+ require 'moped/protocol/query'
50
+ class Query
51
+ class << self
52
+ def deserialize(buffer)
53
+ reply = allocate
54
+ fields.each do |field|
55
+ reply.__send__ :"deserialize_#{field}", buffer
56
+ end
57
+ reply
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ # This patch is so we can create a Reply object as a server
64
+ require 'moped/protocol/reply'
65
+ class Reply
66
+ def initialize(documents, options = {})
67
+ @documents = documents
68
+ @request_id = options[:request_id]
69
+ @response_to = options[:response_to]
70
+ @flags = options[:flags] || []
71
+ @count = documents.length
72
+ @op_code = 1
73
+ end
74
+ end
75
+
76
+
77
+ end
78
+ end
79
+
80
+
81
+ class FakeMongod < EventMachine::Connection
82
+ def initialize(options)
83
+ @options = options
84
+ @request_id = 0
85
+ end
86
+
87
+ def post_init
88
+ if @options[:ssl]
89
+ start_tls(@options[:ssl])
90
+ end
91
+ end
92
+
93
+ def receive_data(data)
94
+ query = Moped::Protocol::Query.deserialize(StringIO.new(data))
95
+ if query.full_collection_name == 'admin.$cmd'
96
+ if query.selector == {'ismaster' => 1}
97
+ send_reply(query,
98
+ :ok => 1,
99
+ :ismaster => 1
100
+ )
101
+ elsif query.selector == {'listDatabases' => 1}
102
+ send_reply(query,
103
+ :ok => 1,
104
+ :databases => [{
105
+ :name => 'test_db'
106
+ }]
107
+ )
108
+ end
109
+ end
110
+ end
111
+
112
+ def send_reply(query, *documents)
113
+ @request_id += 1
114
+ reply = Moped::Protocol::Reply.new(
115
+ documents,
116
+ :request_id => @request_ud,
117
+ :response_to => query.request_id
118
+ )
119
+ send_data reply.serialize
120
+ end
121
+
122
+ end
123
+
124
+ module FakeMongodHelper
125
+
126
+ BASE_PORT = 37017
127
+
128
+ def start_mongod(options={})
129
+ @server = EventMachine.start_server('127.0.0.1', BASE_PORT, FakeMongod, options)
130
+ end
131
+
132
+
133
+ def stop_mongod
134
+ EventMachine.stop_server(@server)
135
+ end
136
+
137
+ end
138
+
139
+ RSpec.configure do |config|
140
+ config.include FakeMongodHelper
141
+
142
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-synchrony-moped
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Lebsack
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: em-synchrony
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: moped
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.4.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.4.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.12.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.12.0
78
+ description: EM-Synchrony-Moped is a Moped driver patch for EM-Synchtony, allowing
79
+ your asynchronous application use non-blocking connections to MongoDB. Moped is
80
+ the MongoDB driver for the Mongoid ORM.
81
+ email: alebsack@gmail.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - Gemfile
88
+ - README.md
89
+ - Rakefile
90
+ - em-synchrony-moped.gemspec
91
+ - lib/em-synchrony/moped.rb
92
+ - spec/moped_spec.rb
93
+ - spec/spec_helper.rb
94
+ - spec/ssl/ca_cert.pem
95
+ - spec/ssl/server.crt
96
+ - spec/ssl/server.key
97
+ - spec/ssl/untrusted.crt
98
+ - spec/ssl/untrusted.key
99
+ - spec/support/simulated_mongod.rb
100
+ homepage:
101
+ licenses: []
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 1.8.25
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Moped driver for EM-Synchrony
124
+ test_files:
125
+ - spec/moped_spec.rb
126
+ - spec/spec_helper.rb
127
+ - spec/ssl/ca_cert.pem
128
+ - spec/ssl/server.crt
129
+ - spec/ssl/server.key
130
+ - spec/ssl/untrusted.crt
131
+ - spec/ssl/untrusted.key
132
+ - spec/support/simulated_mongod.rb
133
+ has_rdoc: