You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2017/01/10 15:59:06 UTC
[45/55] [partial] qpid-proton-j git commit: PROTON-1385: retain
proton-j content only, the rest remains in the other repo at:
https://git-wip-us.apache.org/repos/asf/qpid-proton.git
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl.cpp b/examples/cpp/ssl.cpp
deleted file mode 100644
index 2e901c2..0000000
--- a/examples/cpp/ssl.cpp
+++ /dev/null
@@ -1,238 +0,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.
- *
- */
-
-#include "options.hpp"
-
-#include <proton/connection_options.hpp>
-#include <proton/connection.hpp>
-#include <proton/container.hpp>
-#include <proton/default_container.hpp>
-#include <proton/error_condition.hpp>
-#include <proton/listener.hpp>
-#include <proton/message.hpp>
-#include <proton/messaging_handler.hpp>
-#include <proton/ssl.hpp>
-#include <proton/thread_safe.hpp>
-#include <proton/tracker.hpp>
-#include <proton/transport.hpp>
-
-#include <iostream>
-
-#include "fake_cpp11.hpp"
-
-using proton::connection_options;
-using proton::ssl_client_options;
-using proton::ssl_server_options;
-using proton::ssl_certificate;
-
-// Helper functions defined below.
-bool using_OpenSSL();
-std::string platform_CA(const std::string &base_name);
-ssl_certificate platform_certificate(const std::string &base_name, const std::string &passwd);
-std::string find_CN(const std::string &);
-
-namespace {
- std::string verify_full("full"); // Normal verification
- std::string verify_noname("noname"); // Skip matching host name against the certificate
- std::string verify_fail("fail"); // Force name mismatch failure
- std::string verify(verify_full); // Default for example
- std::string cert_directory;
-
- class example_cert_error : public std::runtime_error
- {
- public:
- explicit example_cert_error(const std::string& s) : std::runtime_error(s) {}
- };
-
-}
-
-
-struct server_handler : public proton::messaging_handler {
- std::string url;
-
- void on_connection_open(proton::connection &c) OVERRIDE {
- std::cout << "Inbound server connection connected via SSL. Protocol: " <<
- c.transport().ssl().protocol() << std::endl;
- c.container().stop_listening(url); // Just expecting the one connection.
- }
-
- void on_transport_error(proton::transport &t) OVERRIDE {
- t.connection().container().stop_listening(url);
- }
-
- void on_message(proton::delivery &, proton::message &m) OVERRIDE {
- std::cout << m.body() << std::endl;
- }
-};
-
-
-class hello_world_direct : public proton::messaging_handler {
- private:
- std::string url;
- server_handler s_handler;
-
- public:
- hello_world_direct(const std::string& u) : url(u) {}
-
- void on_container_start(proton::container &c) OVERRIDE {
- // Configure listener. Details vary by platform.
- ssl_certificate server_cert = platform_certificate("tserver", "tserverpw");
- ssl_server_options ssl_srv(server_cert);
- connection_options server_opts;
- server_opts.ssl_server_options(ssl_srv).handler(s_handler);
- c.server_connection_options(server_opts);
-
- // Configure client with a Certificate Authority database
- // populated with the server's self signed certificate.
- connection_options client_opts;
- if (verify == verify_full) {
- ssl_client_options ssl_cli(platform_CA("tserver"));
- client_opts.ssl_client_options(ssl_cli);
- // The next line is optional in normal use. Since the
- // example uses IP addresses in the connection string, use
- // the virtual_host option to set the server host name
- // used for certificate verification:
- client_opts.virtual_host("test_server");
- } else if (verify == verify_noname) {
- // Downgrade the verification from VERIFY_PEER_NAME to VERIFY_PEER.
- ssl_client_options ssl_cli(platform_CA("tserver"), proton::ssl::VERIFY_PEER);
- client_opts.ssl_client_options(ssl_cli);
- } else if (verify == verify_fail) {
- ssl_client_options ssl_cli(platform_CA("tserver"));
- client_opts.ssl_client_options(ssl_cli);
- client_opts.virtual_host("wrong_name_for_server"); // Pick any name that doesn't match.
- } else throw std::logic_error("bad verify mode: " + verify);
-
- c.client_connection_options(client_opts);
- s_handler.url = url;
- c.listen(url);
- c.open_sender(url);
- }
-
- void on_connection_open(proton::connection &c) OVERRIDE {
- std::string subject = c.transport().ssl().remote_subject();
- std::cout << "Outgoing client connection connected via SSL. Server certificate identity " <<
- find_CN(subject) << std::endl;
- }
-
- void on_transport_error(proton::transport &t) OVERRIDE {
- std::string err = t.error().what();
- if (err.find("certificate"))
- throw example_cert_error(err);
- }
-
- void on_sendable(proton::sender &s) OVERRIDE {
- proton::message m;
- m.body("Hello World!");
- s.send(m);
- s.close();
- }
-
- void on_tracker_accept(proton::tracker &t) OVERRIDE {
- // All done.
- t.connection().close();
- }
-};
-
-int main(int argc, char **argv) {
- // Pick an "unusual" port since we are going to be talking to
- // ourselves, not a broker.
- // Note the use of "amqps" as the URL scheme to denote a TLS/SSL connection.
- std::string address("amqps://127.0.0.1:8888/examples");
- example::options opts(argc, argv);
- opts.add_value(address, 'a', "address", "connect and send to URL", "URL");
- opts.add_value(cert_directory, 'c', "cert_directory",
- "directory containing SSL certificates and private key information", "CERTDIR");
- opts.add_value(verify, 'v', "verify", "verify type: \"minimum\", \"full\", \"fail\"", "VERIFY");
-
- try {
- opts.parse();
-
- size_t sz = cert_directory.size();
- if (sz && cert_directory[sz -1] != '/')
- cert_directory.append("/");
- else cert_directory = "ssl_certs/";
-
- if (verify != verify_noname && verify != verify_full && verify != verify_fail)
- throw std::runtime_error("bad verify argument: " + verify);
-
- hello_world_direct hwd(address);
- proton::default_container(hwd).run();
- return 0;
- } catch (const example_cert_error& ce) {
- if (verify == verify_fail) {
- std::cout << "Expected failure of connection with wrong peer name: " << ce.what() << std::endl;
- return 0;
- }
- std::cerr << "unexpected internal certificate failure: " << ce.what() << std::endl;
- } catch (const std::exception& e) {
- std::cerr << e.what() << std::endl;
- }
- return 1;
-}
-
-
-bool using_OpenSSL() {
- // Current defaults.
-#if defined(WIN32)
- return false;
-#else
- return true;
-#endif
-}
-
-ssl_certificate platform_certificate(const std::string &base_name, const std::string &passwd) {
- if (using_OpenSSL()) {
- // The first argument will be the name of the file containing the public certificate, the
- // second argument will be the name of the file containing the private key.
- return ssl_certificate(cert_directory + base_name + "-certificate.pem",
- cert_directory + base_name + "-private-key.pem", passwd);
- }
- else {
- // Windows SChannel
- // The first argument will be the database or store that contains one or more complete certificates
- // (public and private data). The second will be an optional name of the certificate in the store
- // (not used in this example with one certificate per store).
- return ssl_certificate(cert_directory + base_name + "-full.p12", "", passwd);
- }
-}
-
-std::string platform_CA(const std::string &base_name) {
- if (using_OpenSSL()) {
- // In this simple example with self-signed certificates, the peer's certificate is the CA database.
- return cert_directory + base_name + "-certificate.pem";
- }
- else {
- // Windows SChannel. Use a pkcs#12 file with just the peer's public certificate information.
- return cert_directory + base_name + "-certificate.p12";
- }
-}
-
-std::string find_CN(const std::string &subject) {
- // The subject string is returned with different whitespace and component ordering between platforms.
- // Here we just return the common name by searching for "CN=...." in the subject, knowing that
- // the test certificates do not contain any escaped characters.
- size_t pos = subject.find("CN=");
- if (pos == std::string::npos) throw std::runtime_error("No common name in certificate subject");
- std::string cn = subject.substr(pos);
- pos = cn.find(',');
- return pos == std::string::npos ? cn : cn.substr(0, pos);
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/README.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/README.txt b/examples/cpp/ssl_certs/README.txt
deleted file mode 100644
index 9a8a4f9..0000000
--- a/examples/cpp/ssl_certs/README.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory contains basic self signed test certificates for use by
-proton examples.
-
-The ".pem" files are in the format expected by proton implementations
-using OpenSSL. The ".p12" file are for Windows implementations using
-SChannel.
-
-The commands used to generate the certificates follow.
-
-
-make_pn_cert()
-{
- name=$1
- subject=$2
- passwd=$3
- # create the pem files
- openssl req -newkey rsa:2048 -keyout $name-private-key.pem -out $name-certificate.pem -subj $subject -passout pass:$passwd -x509 -days 3650
- # create the p12 files
- openssl pkcs12 -export -out $name-full.p12 -passin pass:$passwd -passout pass:$passwd -inkey $name-private-key.pem -in $name-certificate.pem -name $name
- openssl pkcs12 -export -out $name-certificate.p12 -in $name-certificate.pem -name $name -nokeys -passout pass:
-}
-
-make_pn_cert tserver /CN=test_server/OU=proton_test tserverpw
-make_pn_cert tclient /CN=test_client/OU=proton_test tclientpw
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tclient-certificate.p12
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tclient-certificate.p12 b/examples/cpp/ssl_certs/tclient-certificate.p12
deleted file mode 100644
index 4d0e000..0000000
Binary files a/examples/cpp/ssl_certs/tclient-certificate.p12 and /dev/null differ
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tclient-certificate.pem
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tclient-certificate.pem b/examples/cpp/ssl_certs/tclient-certificate.pem
deleted file mode 100644
index 8088e2e..0000000
--- a/examples/cpp/ssl_certs/tclient-certificate.pem
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDKzCCAhOgAwIBAgIJAIV7frIjftgcMA0GCSqGSIb3DQEBCwUAMCwxFDASBgNV
-BAMMC3Rlc3RfY2xpZW50MRQwEgYDVQQLDAtwcm90b25fdGVzdDAeFw0xNTExMjcx
-ODEwMzlaFw0yNTExMjQxODEwMzlaMCwxFDASBgNVBAMMC3Rlc3RfY2xpZW50MRQw
-EgYDVQQLDAtwcm90b25fdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAPCIS4qUdOtQplUxZ6WW0LXcvosqFP6qOiCARLSEWpR3B8bq213rzefwwfcM
-4TtMr88bP+huLKmlyMfwpl8yB88eXkscPgaAce2zk24urWkFXKSQ6GPitWBLGqBa
-V+W0wJ4mfW7MwefVslWfGXI381QEUlBHjkFG30AtzMMTRj2GK2JqUlRXZPljGyB7
-WcXwxcoS+HkKV7FtHWSkLAzyXwQ9vsCUEYdWTUaGXfCUNRSRV7h1LIANbu03NxV0
-XdEl7WXcr7tuTw3axeUGhRFVhLegrxKLuZTTno4aAJnEr8uaDzjxvXnv3Ne2igvy
-gRfZgOMx+XrZEob9OpAoRghQt4cCAwEAAaNQME4wHQYDVR0OBBYEFE4vbyiM0RjG
-TLMLLGGhMZE/5x1GMB8GA1UdIwQYMBaAFE4vbyiM0RjGTLMLLGGhMZE/5x1GMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAErr/rvLS9Ig0UCMwh1J1lA9
-/gvXf93iIK/SjrFIAqYRmfZxg4husfoes8t2hFUeuqoH05TuSOoXG8p8DpgTSGmF
-jAFe+T90vJZTm0oqZkkkI/hdzjGQoHURRp9/O2Z/lm39KSKGVAN5pUWCUDi/G5iS
-P9LZPJN6a5syXMrR6x62IPxAXowlpXkRghKClF3zPOaOBTzT1V27EkI8IEgC+p45
-246EooLnw8ibB+ucNc3KHNzpgKGVd/622+I+Q5eg9AT9PLFttP+R2ECsrVDDPYuA
-p0qaSnwgeozj/d6K3FOgKKEKbzBmpWgkv0jdcVk18aPMHypI/RDtZ/+3ET2Ksi8=
------END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tclient-full.p12
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tclient-full.p12 b/examples/cpp/ssl_certs/tclient-full.p12
deleted file mode 100644
index ad2d7d3..0000000
Binary files a/examples/cpp/ssl_certs/tclient-full.p12 and /dev/null differ
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tclient-private-key.pem
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tclient-private-key.pem b/examples/cpp/ssl_certs/tclient-private-key.pem
deleted file mode 100644
index e5c114d..0000000
--- a/examples/cpp/ssl_certs/tclient-private-key.pem
+++ /dev/null
@@ -1,30 +0,0 @@
------BEGIN ENCRYPTED PRIVATE KEY-----
-MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQICy6ghWp45z4CAggA
-MBQGCCqGSIb3DQMHBAiVdDoo4NIghQSCBMixGm1bm/omMxsaKnIPO7zm5dyLexJ+
-yTFpmh2KV7kQqmpzCyIOdoG6K8YqFnie2XdFWm3S8faRHoMq54bDmyEWIxfQPq5f
-I1iYFbIZkbnhUvK53RActsEUMf0locS4xylU7VQK3XTAwp0TVip3Lp3ehEMEdcXL
-iUWibGsoTPKcY9MIWGXZAJXsEXoeHt6k2hHo1G4E0/Bi6mLW1LY/cxZCjHTGD6qI
-Kt54SCCDvinqVa+rixw6yX9F14EA6bhALami8e+Ccd3lqHOyYlXcBaSS1ezCg6ig
-oNK97mC+gEGy1KlkZDKWXclFoOCBXRBe4DByre6Rlq3yeI9L42bvAuSBSmf5QT5g
-73Yl8vjEAKR65awBT09dPuKu7t+Fb6vkwF8/t+uyj9IuL+42UuXhMLK3ohf+6DbU
-8/zB4y3GXI80QmWM0+Wx4n6khFhPFLHt2q0Sn6V9PG1vtHyiq50oSCoyrPQLaecp
-hefnMCFBYTcT3JUwmoVGGy0boIAwL7T4aGsMt7QhwOx5tU35tKFxyY7m4fX14AKo
-2EIy+TPQwCGkGf3Puy/Pc9VA8IAxB5+WwSrjk+NeCv88eIX7gy43k4rCr+OmD9FF
-wknr3xoP3KYhNXjdZ4Ep/1UHSK+JAtzzbNLQjDcqN+gQPg/yUX6ih0j5K3Wvh9bK
-E/DvzbpJroUZPgzR+8z5O68CfsD+OIdpHBFTKqAFmzvUuqpADpr998LdCjD+lW+V
-xZZgZa8KEblwgiH3fdGbYl46Ho1zrZisf439DbqyybAuBIQB4NSZcL/MAgVGO17k
-QDpVElWZWYrFm4CFTcvS2HvIzRmbefF5m5oJedsN7Q6WQCp+3gnwYx1xIOknd7pW
-N4AHNnqjscSj9yACj/EiBVKAKNnC5H7ZGZTsaAjMETZyjLXfI2AZ3Fviz4zFR+oz
-NkAfFB6WUpRpl7H02FzrzYT7XkkLcXd6H6g+mv2iDa9uKWk/PS2QlqnJt8/dHEHD
-JKTG331yDK5GHlKAVGF3nP5BwFGgTQMuSoeiOervMXPUwDpQ8OaYkuaRej0cZLgT
-kAF9sUjqdsoYNcXDFHALp6y5g8qYkfrxrlIbKs82zIsmB5I+dtZbUaD3a0zAUrmW
-5Xm3Pc9dVP0EXKwfHz6zqPReEw2yYLisB5IoHd4M2wa3GzHBdra1ij4QTmvd3o7e
-buGFoX8KJQAcig0zpbYkoDP2gPhIh9rY4unVPQNX1Q8/wRsiJAZZsYvZY+A+SmuZ
-bwSwk+8ZJRsFzdYYYhQeRytD5cDAIQiClcI5Yj4T9dWQV/gf0N/wIBDNTMp0jJAy
-1l7PuXTfGZodNJWZH0oqsrNoWbn/k67NildvvofIKX+h09Nxszr670Pvj0qoHd5/
-CWq30lnxoJBUgbikFOz6ZuuHi/ZiCXL+haH+v8hJKN5ptRKnyYJQHchRB/IOGRoT
-5lmWxo8a7K+yXhp0VBDHJfw3685ms0xQX8Xj4X3MEuN64zd0fB1JmhtP12ydK85J
-ABawNKlRQPw5weckwtCviXQX+vX25S/xu3xA6IuqlHyqL/1t3DICzuxeOyT2mZxD
-tKQxEgNihPvu32vn9m74qA3adEaxuWPRkPZuTeITHOkMTZolvqYX/5olBsSgYwka
-7/g=
------END ENCRYPTED PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tserver-certificate.p12
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tserver-certificate.p12 b/examples/cpp/ssl_certs/tserver-certificate.p12
deleted file mode 100644
index f38b67d..0000000
Binary files a/examples/cpp/ssl_certs/tserver-certificate.p12 and /dev/null differ
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tserver-certificate.pem
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tserver-certificate.pem b/examples/cpp/ssl_certs/tserver-certificate.pem
deleted file mode 100644
index 86231f3..0000000
--- a/examples/cpp/ssl_certs/tserver-certificate.pem
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDKzCCAhOgAwIBAgIJAPnYOOQCJ3kDMA0GCSqGSIb3DQEBCwUAMCwxFDASBgNV
-BAMMC3Rlc3Rfc2VydmVyMRQwEgYDVQQLDAtwcm90b25fdGVzdDAeFw0xNTExMjcx
-ODEwMzlaFw0yNTExMjQxODEwMzlaMCwxFDASBgNVBAMMC3Rlc3Rfc2VydmVyMRQw
-EgYDVQQLDAtwcm90b25fdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAKJNB78lgw4KtXDAvXocTLud6mbn6zgfB6ETIF+kcrukOH9DnPxjLBBM4Lig
-sp1+kmeudFK5/X8riDrvIW52b/rlEBLgLB+oDtI74m6OTbBs9L+FUFYOuxApetQF
-qoJy2vf9pWfy4uku24vCpeo7eVLi6ypu4lXE3LR+Km3FruHI1NKonHBMhwXSOWqF
-pYM6/4IZJ4fbV0+eU0Jrx+05s6XHg5vone2BVJKxeSIBje+zWnNnh8+qG0Z70Jgp
-aMetME5KGnLNgD1okpH0vb3lwjvuqkkx4WswGVZGbLLkSqqBpXPyM9fCFVy5aKSL
-DBq7IABQtO67O2nBzK3OyigHrUUCAwEAAaNQME4wHQYDVR0OBBYEFGV1PY0FCFbJ
-gpcDVKI6JGiRTt3kMB8GA1UdIwQYMBaAFGV1PY0FCFbJgpcDVKI6JGiRTt3kMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIx1TOTGWnnbpan4bse7wuvH
-GYSNDJhoTVS+X1TC63xukJD1JBAsCNTqg/ZV6lN3XEl7vvOXfGoCiyXM6a9XOKUo
-gSDtMrIr+wTh6Ss1yRO8QcCJmxH5JDXNu1ojtwsjFW/vneI4IL9kwpDsSlMQEX/E
-EkkQwtAx/Cvfe7pecZL4qSeykJOUMTts9H8fCAZqEiRZBA3ugJxqF8jwLP3DoFVQ
-6QZzKDY6CSPqfMnVb5i0MAIYVDpau+e3N9dgQpZD22F/zbua0OVbfAPdiRMnYxML
-FT4sxLnh+5YVqwpVWbEKp4onHe2Fq6YIvAxUYAJ3SBA2C8O2RAVKWxf1jko3jYI=
------END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tserver-full.p12
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tserver-full.p12 b/examples/cpp/ssl_certs/tserver-full.p12
deleted file mode 100644
index d4a0e40..0000000
Binary files a/examples/cpp/ssl_certs/tserver-full.p12 and /dev/null differ
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_certs/tserver-private-key.pem
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_certs/tserver-private-key.pem b/examples/cpp/ssl_certs/tserver-private-key.pem
deleted file mode 100644
index 91dcf0e..0000000
--- a/examples/cpp/ssl_certs/tserver-private-key.pem
+++ /dev/null
@@ -1,30 +0,0 @@
------BEGIN ENCRYPTED PRIVATE KEY-----
-MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI1cT0c2J3GcQCAggA
-MBQGCCqGSIb3DQMHBAi1hxSX2LJ+EgSCBMheHJ0iXr5A36Natjk/LcAEeKUMT9s+
-sMzoQceCWe8qMlQluWksr9iDdZ4JRIE8cpK8dbmx4dLY/SShUzdlhJHCSa4zZBHq
-8cZ/jGUF/RF1rqdgjK589eUq+uOl3/gXKzG/SxBqayy6PSn12kX3qnvmlkXCmtwU
-lg+iBm5wRcJ0MyVHaJkyA8sW8gr186C/VAau6Yu0crQXN7NRo9snrd4ewuYMIEhZ
-hgaG9XsYQWB1bPhAaKj80CZGxsQbJyTwcbKKkB3IY4WXx8mmhuiNl+vKT3HBJ9Ju
-YB6tgIjs8CJ4X2P4aU3yNJwG1QldgHSqmFGQ19bcZAw3s3kzwjdzRf4H2V16XOBd
-zQ5AEs/ffVMzMIAfkb1gYwgunZ2CVwwDJ2mi1RcgkX+Og2aFQc+fxXcVOnDcGLxV
-6fuCuZ2lsXfoiIyRh9kj3L75N12GtVUvgBdnMuOc1wPw6XnGQtDwt0acJpdexLMG
-k0j57r/gcgzTcmF3qNM+y9L/HLssgrJkvVJw2Np5gmtIyfDocsDUWUbClS4dTpYf
-oTngUTU+vWtHBuaUnb+f5/WJaRS/S7mmR8usbVG3i9WnEr/vlPJpbJFSjW2S6u/H
-7cFxKUmmBZsSuEv/EKt9a+Sh62kprOChm4myqfCI1/gvNKfUZC6m0Vp8zf+2LgAq
-2RgbMuqysMjWUtV4kDRZT7oCYckUDwsCHdbLES3nmVrtBk2ShMKHBpDp8/GoRuiV
-jdV7/EjKM/M1kXtFYYe3z7Mxv++lKYIJ7bNwVrQ8nrhce/VwHw6D5emWXNCJXhKZ
-FW7EM2ZOZ9eaKOlCsIi8sbjV6Yie9IY6HJKKmi3CpO0Tv5kLBdHkru8vGCSFm3O1
-n7wz7Ys5FBSlZ19X0NwQSCQX1Q4w+tido6i1SCRX0qJEdTNGuGwVXMHCf4/1zyHV
-hj8vnxh8fzo79LFrwlTTgwLg1Mr8sEUFFDJ/raJ1AhFXi8n24trtNR8EHxRW8wtD
-CLCKaqkEqfBiFXK/Yq3RrefCayPHiD+DaNsI8BwefMGpED3vD8YYCjAzXNPh/CSF
-sc1i1jWMzbJhzOoFSPNXhlfusbUFMFQ/6olatmH47SY6HBBOL3DDP5uQ0jw8P454
-QBjlMOpEZmZxO6TcEtJwu0vzgog4rQ5g3NWy6SIpjWehNwTynLt7yM3R5WTI6cZs
-0GTv/rqo2/SUoNsFmnGIUwj/DrBe4XOAq1nS2ZlEctxKhBsKH0hMFp6D1rXOzrgl
-bwcq+oistoB0TLcThShyNgSqzW1znQ1n5SVUk9b5rRhSttJxn3yOMewH0i3v8bPo
-HOhP5kaGjblPsCYyhlL/SNVF0OXEGTwLNey7FQdWFOwVwTRRXe7k+uGZ2d5hg+Jn
-It/trDZ1RDYbVmB7/Qy73c16J4mvhOUJ2de5ZciFBjkidbiiUKLj9xnjK9k9Sauo
-MKhNnDMAEU5VDQM3xNe5BRdX8dFLwfF5H64sU3nROF83aUnDgvfFEowYPnCuPYfm
-m4aQHfoBSg4j3v1OeOwktcl+Q2TjxPHfWhbWeRBfxOTqQ/suYhnQChuFSK/qyo9K
-ccgotqghhunRsWMoZT25H7AZM6yKb1sMz/0oyMRIKeGqoYh+ULM5XLY0xNYd4/xU
-WtQ=
------END ENCRYPTED PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/ssl_client_cert.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_client_cert.cpp b/examples/cpp/ssl_client_cert.cpp
deleted file mode 100644
index 630e74b..0000000
--- a/examples/cpp/ssl_client_cert.cpp
+++ /dev/null
@@ -1,197 +0,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.
- *
- */
-
-#include <proton/connection.hpp>
-#include <proton/connection_options.hpp>
-#include <proton/container.hpp>
-#include <proton/default_container.hpp>
-#include <proton/listener.hpp>
-#include <proton/message.hpp>
-#include <proton/messaging_handler.hpp>
-#include <proton/sasl.hpp>
-#include <proton/ssl.hpp>
-#include <proton/thread_safe.hpp>
-#include <proton/tracker.hpp>
-#include <proton/transport.hpp>
-
-#include <iostream>
-
-#include "fake_cpp11.hpp"
-
-using proton::connection_options;
-using proton::ssl_client_options;
-using proton::ssl_server_options;
-using proton::ssl_certificate;
-using proton::sasl;
-
-// Helper functions defined below.
-bool using_OpenSSL();
-std::string platform_CA(const std::string &base_name);
-ssl_certificate platform_certificate(const std::string &base_name, const std::string &passwd);
-static std::string cert_directory;
-static std::string find_CN(const std::string &);
-
-
-struct server_handler : public proton::messaging_handler {
- proton::listener listener;
-
- void on_connection_open(proton::connection &c) OVERRIDE {
- std::cout << "Inbound server connection connected via SSL. Protocol: " <<
- c.transport().ssl().protocol() << std::endl;
- if (c.transport().sasl().outcome() == sasl::OK) {
- std::string subject = c.transport().ssl().remote_subject();
- std::cout << "Inbound client certificate identity " << find_CN(subject) << std::endl;
- }
- else {
- std::cout << "Inbound client authentication failed" <<std::endl;
- c.close();
- }
- listener.stop();
- }
-
- void on_message(proton::delivery &, proton::message &m) OVERRIDE {
- std::cout << m.body() << std::endl;
- }
-};
-
-
-class hello_world_direct : public proton::messaging_handler {
- private:
- std::string url;
- server_handler s_handler;
-
- public:
- hello_world_direct(const std::string& u) : url(u) {}
-
- void on_container_start(proton::container &c) OVERRIDE {
- // Configure listener. Details vary by platform.
- ssl_certificate server_cert = platform_certificate("tserver", "tserverpw");
- std::string client_CA = platform_CA("tclient");
- // Specify an SSL domain with CA's for client certificate verification.
- ssl_server_options srv_ssl(server_cert, client_CA);
- connection_options server_opts;
- server_opts.ssl_server_options(srv_ssl).handler(s_handler);
- server_opts.sasl_allowed_mechs("EXTERNAL");
- c.server_connection_options(server_opts);
-
- // Configure client.
- ssl_certificate client_cert = platform_certificate("tclient", "tclientpw");
- std::string server_CA = platform_CA("tserver");
- // Since the test certifcate's credentials are unlikely to match this host's name, downgrade the verification
- // from VERIFY_PEER_NAME to VERIFY_PEER.
- ssl_client_options ssl_cli(client_cert, server_CA, proton::ssl::VERIFY_PEER);
- connection_options client_opts;
- client_opts.ssl_client_options(ssl_cli).sasl_allowed_mechs("EXTERNAL");
- c.client_connection_options(client_opts);
-
- s_handler.listener = c.listen(url);
- c.open_sender(url);
- }
-
- void on_connection_open(proton::connection &c) OVERRIDE {
- std::string subject = c.transport().ssl().remote_subject();
- std::cout << "Outgoing client connection connected via SSL. Server certificate identity " <<
- find_CN(subject) << std::endl;
- }
-
- void on_sendable(proton::sender &s) OVERRIDE {
- proton::message m;
- m.body("Hello World!");
- s.send(m);
- s.close();
- }
-
- void on_tracker_accept(proton::tracker &t) OVERRIDE {
- // All done.
- t.connection().close();
- }
-};
-
-int main(int argc, char **argv) {
- try {
- // Pick an "unusual" port since we are going to be talking to ourselves, not a broker.
- // Note the use of "amqps" as the URL scheme to denote a TLS/SSL connection.
- std::string url = argc > 1 ? argv[1] : "amqps://127.0.0.1:8888/examples";
- // Location of certificates and private key information:
- if (argc > 2) {
- cert_directory = argv[2];
- size_t sz = cert_directory.size();
- if (sz && cert_directory[sz -1] != '/')
- cert_directory.append("/");
- }
- else cert_directory = "ssl_certs/";
-
- hello_world_direct hwd(url);
- proton::default_container(hwd).run();
- return 0;
- } catch (const std::exception& e) {
- std::cerr << e.what() << std::endl;
- }
- return 1;
-}
-
-
-bool using_OpenSSL() {
- // Current defaults.
-#if defined(WIN32)
- return false;
-#else
- return true;
-#endif
-}
-
-ssl_certificate platform_certificate(const std::string &base_name, const std::string &passwd) {
- if (using_OpenSSL()) {
- // The first argument will be the name of the file containing the public certificate, the
- // second argument will be the name of the file containing the private key.
- return ssl_certificate(cert_directory + base_name + "-certificate.pem",
- cert_directory + base_name + "-private-key.pem", passwd);
- }
- else {
- // Windows SChannel
- // The first argument will be the database or store that contains one or more complete certificates
- // (public and private data). The second will be an optional name of the certificate in the store
- // (not used in this example with one certificate per store).
- return ssl_certificate(cert_directory + base_name + "-full.p12", "", passwd);
- }
-}
-
-std::string platform_CA(const std::string &base_name) {
- if (using_OpenSSL()) {
- // In this simple example with self-signed certificates, the peer's certificate is the CA database.
- return cert_directory + base_name + "-certificate.pem";
- }
- else {
- // Windows SChannel. Use a pkcs#12 file with just the peer's public certificate information.
- return cert_directory + base_name + "-certificate.p12";
- }
-}
-
-std::string find_CN(const std::string &subject) {
- // The subject string is returned with different whitespace and component ordering between platforms.
- // Here we just return the common name by searching for "CN=...." in the subject, knowing that
- // the test certificates do not contain any escaped characters.
- size_t pos = subject.find("CN=");
- if (pos == std::string::npos) throw std::runtime_error("No common name in certificate subject");
- std::string cn = subject.substr(pos);
- pos = cn.find(',');
- return pos == std::string::npos ? cn : cn.substr(0, pos);
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/tutorial.dox
----------------------------------------------------------------------
diff --git a/examples/cpp/tutorial.dox b/examples/cpp/tutorial.dox
deleted file mode 100644
index 56345a1..0000000
--- a/examples/cpp/tutorial.dox
+++ /dev/null
@@ -1,432 +0,0 @@
-// -*-markdown-*-
-// NOTE: doxygen can include markdown pages directly but there seems to be a bug
-// that shows messed-up line numbers in \skip \until code extracts. This file
-// is markdown wrapped in a doxygen comment - which works. The file is best viewed/editied
-// as markdown.
-
-/**
-
-@page tutorial Tutorial
-
-This is a brief tutorial that will walk you through the fundamentals
-of building messaging applications in incremental steps. There are
-further examples, in addition the ones mentioned in the tutorial.
-
-Proton provides an "event-driven" programming model, where you
-implement a subclass of `proton::messaging_handler` and override
-functions that react to various AMQP events (connections opening and
-closing, messages being delivered, and so on).
-
-The examples below show how to implement handlers for clients and
-servers and how to run them using the `proton::default_container`, a
-portable, easy-to-use way to build single-threaded clients or servers.
-
-Some of the examples require an AMQP *broker* that can receive, store,
-and send messages. @ref broker.hpp and @ref broker.cpp define a simple
-example broker. If run without arguments, it listens on
-`0.0.0.0:5672`, the standard AMQP port on all network interfaces. To
-use a different port or network interface:
-
- broker -a <host>:<port>
-
-Instead of the example broker, you can use any AMQP 1.0-compliant
-broker. You must configure your broker to have a queue (or topic)
-named "examples".
-
-The `helloworld` examples take an optional URL argument. The other
-examples take an option `-a URL`. A URL looks like this:
-
- HOST:PORT/ADDRESS
-
-It usually defaults to `127.0.0.1:5672/examples`, but you can change
-this if your broker is on a different host or port, or you want to use
-a different queue or topic name (the ADDRESS part of the URL). URL
-details are at `proton::url`.
-
-Hello World!
-------------
-
-\dontinclude helloworld.cpp
-
-Tradition dictates that we start with Hello World! This example
-demonstrates sending and receiving by sending a message to a broker
-and then receiving the same message back. In a realistic system the
-sender and receiver would normally be in different processes. The
-complete example is @ref helloworld.cpp
-
-We will include the following classes: `proton::default_container` (an
-implementation of `proton::container`) runs an event loop which
-dispatches events to a `proton::messaging_handler`. This allows a
-*reactive* style of programming which is well suited to messaging
-applications. `proton::connection` and `proton::delivery` are AMQP
-entities used in the handler functions. `proton::url` is a simple
-parser for the URL format mentioned above.
-
-\skip proton/connection
-\until proton/url
-
-We will define a class `hello_world` which is a subclass of
-`proton::messaging_handler` and overrides functions to handle the
-events of interest in sending and receiving a message.
-
-\skip class hello_world
-\until {}
-
-`proton::messaging_handler::on_container_start()` is called when the
-event loop first starts. We handle that by establishing a connection
-and creating a sender and a receiver.
-
-\skip on_container_start
-\until }
-\until }
-
-`proton::messaging_handler::on_sendable()` is called when the message
-can be transferred over the associated sender link to the remote
-peer. We create a `proton::message`, set the message body to `"Hello
-World!"`, and send the message. Then we close the sender, since we
-only want to send one message. Closing the sender will prevent further
-calls to `proton::messaging_handler::on_sendable()`.
-
-\skip on_sendable
-\until }
-
-`proton::messaging_handler::on_message()` is called when a message is
-received. We just print the body of the message and close the
-connection, as we only want one message
-
-\skip on_message
-\until }
-
-The message body is a `proton::value`, see the documentation for more on how to
-extract the message body as type-safe C++ values.
-
-Our `main` function creates an instance of the `hello_world` handler
-and a `proton::default_container` using that handler. Calling
-`proton::container::run` sets things in motion and returns when we
-close the connection as there is nothing further to do. It may throw
-an exception, which will be a subclass of `proton::error`. That in
-turn is a subclass of `std::exception`.
-
-\skip main
-\until }
-\until }
-\until }
-
-Hello World, direct!
---------------------
-
-\dontinclude helloworld_direct.cpp
-
-Though often used in conjunction with a broker, AMQP does not
-*require* this. It also allows senders and receivers to communicate
-directly if desired.
-
-We will modify our example to send a message directly to itself. This
-is a bit contrived but illustrates both sides of the direct send and
-receive scenario. The full code is at @ref helloworld_direct.cpp.
-
-The first difference is that, rather than creating a receiver on the
-same connection as our sender, we listen for incoming connections by
-invoking the `proton::container::listen()` method on the container.
-
-\skip on_container_start
-\until }
-
-As we only need then to initiate one link, the sender, we can do that
-by passing in a url rather than an existing connection, and the
-connection will also be automatically established for us.
-
-We send the message in response to the
-`proton::messaging_handler::on_sendable()` callback and print the
-message out in response to the
-`proton::messaging_handler::on_message()` callback exactly as before.
-
-\skip on_sendable
-\until }
-\until }
-
-However, we also handle two new events. We now close the connection
-from the sender's side once the message has been accepted. The
-acceptance of the message is an indication of successful transfer to
-the peer. We are notified of that event through the
-`proton::messaging_handler::on_tracker_accept()` callback.
-
-\skip on_tracker_accept
-\until }
-
-Then, once the connection has been closed, of which we are notified
-through the `proton::messaging_handler::on_connection_close()`
-callback, we stop accepting incoming connections. A that point there
-is no work to be done, the event loop exits, and the
-`proton::container::run()` method returns.
-
-\skip on_connection_close
-\until }
-
-So now we have our example working without a broker involved!
-
-Note that for this example we pick an "unusual" port 8888 since we are talking
-to ourselves rather than a broker.
-
-\skipline url =
-
-Asynchronous send and receive
------------------------------
-
-Of course, these `Hello World!` examples are very artificial,
-communicating as they do over a network connection but with the same
-process. A more realistic example involves communication between
-separate processes, which could indeed be running on completely
-separate machines.
-
-Let's separate the sender from the receiver, and transfer more than a
-single message between them.
-
-We'll start with a simple sender, @ref simple_send.cpp.
-
-\dontinclude simple_send.cpp
-
-As with the previous example, we define the application logic in a
-class that handles events. Because we are transferring more than one
-message, we need to keep track of how many we have sent. We'll use a
-`sent` member variable for that. The `total` member variable will
-hold the number of messages we want to send.
-
-\skip class simple_send
-\until total
-
-As before, we use the
-`proton::messaging_handler::on_container_start()` event to establish
-our sender link over which we will transfer messages.
-
-\skip on_container_start
-\until }
-
-AMQP defines a credit-based flow-control mechanism. Flow control
-allows the receiver to control how many messages it is prepared to
-receive at a given time and thus prevents any component being
-overwhelmed by the number of messages it is sent.
-
-In the `proton::messaging_handler::on_sendable()` callback, we check
-that our sender has credit before sending messages. We also check that
-we haven't already sent the required number of messages.
-
-\skip on_sendable
-\until }
-\until }
-
-The `proton::sender::send()` call above is asynchronous. When it
-returns, the message has not yet actually been transferred across the
-network to the receiver. By handling the
-`proton::messaging_handler::on_tracker_accept()` event, we can get
-notified when the receiver has received and accepted the message. In
-our example we use this event to track the confirmation of the
-messages we have sent. We only close the connection and exit when the
-receiver has received all the messages we wanted to send.
-
-\skip on_tracker_accept
-\until }
-\until }
-
-If we are disconnected after a message is sent and before it has been
-confirmed by the receiver, it is said to be "in doubt". We don't know
-whether or not it was received. In this example, we will handle that
-by resending any in-doubt messages. This is known as an
-"at-least-once" guarantee, since each message should eventually be
-received at least once, though a given message may be received more
-than once (i.e., duplicates are possible). In the
-`proton::messaging_handler::on_transport_close()` callback, we reset
-the sent count to reflect only those that have been confirmed. The
-library will automatically try to reconnect for us, and when our
-sender is sendable again, we can restart from the point we know the
-receiver got to.
-
-\skip on_transport_close
-\until }
-
-\dontinclude simple_recv.cpp
-
-Now let's look at the corresponding receiver, @ref simple_recv.cpp.
-
-This time we'll use an `expected` member variable for for the number
-of messages we expect and a `received` variable to count how many we
-have received so far.
-
-\skip class simple_recv
-\until received
-
-We handle `proton::messaging_handler::on_container_start()` by
-creating our receiver, much like we did for the sender.
-
-\skip on_container_start
-\until }
-
-We also handle the `proton::messaging_handler::on_message()` event for
-received messages and print the message out as in the `Hello World!`
-examples. However, we add some logic to allow the receiver to wait
-for a given number of messages and then close the connection and
-exit. We also add some logic to check for and ignore duplicates, using
-a simple sequential ID scheme.
-
-\skip on_message
-\until }
-
-Direct send and receive
------------------------
-
-Sending between these two examples requires an intermediary broker
-since neither accepts incoming connections. AMQP allows us to send
-messages directly between two processes. In that case, one or other of
-the processes needs to accept incoming connections. Let's create a
-modified version of the receiving example that does this with @ref
-direct_recv.cpp.
-
-\dontinclude direct_recv.cpp
-
-There are only two differences here. Instead of initiating a link (and
-implicitly a connection), we listen for incoming connections.
-
-\skip on_container_start
-\until }
-
-When we have received all the expected messages, we then stop
-listening for incoming connections by calling
-`proton::listener::stop()`
-
-\skip on_message
-\until }
-\until }
-\until }
-\until }
-
-You can use the @ref simple_send.cpp example to send to this receiver
-directly. (Note: you will need to stop any broker that is listening on
-the 5672 port, or else change the port used by specifying a different
-address to each example via the `-a` command-line switch).
-
-We can also modify the sender to allow the original receiver to
-connect to it, in @ref direct_send.cpp. Again, that requires just two
-modifications:
-
-\dontinclude direct_send.cpp
-
-As with the modified receiver, instead of initiating establishment of a
-link, we listen for incoming connections.
-
-\skip on_container_start
-\until }
-
-When we have received confirmation of all the messages we sent, we call
-`container::listener::stop()` to exit.
-
-\skip on_tracker_accept
-\until }
-\until }
-
-To try this modified sender, run the original @ref simple_recv.cpp
-against it.
-
-The symmetry in the underlying AMQP wire protocol that enables this is
-quite unique and elegant, and in reflecting this the Proton API
-provides a flexible toolkit for implementing all sorts of interesting
-intermediaries.
-
-Request and response
---------------------
-
-A common pattern is to send a request message and expect a response
-message in return. AMQP has special support for this pattern. Let's
-have a look at a simple example. We'll start with @ref server.cpp, the
-program that will process the request and send the response. Note that
-we are still using a broker in this example.
-
-Our server will provide a very simple service: it will respond with
-the body of the request converted to uppercase.
-
-\dontinclude server.cpp
-\skip class server
-\until };
-
-The code here is not too different from the simple receiver example.
-However, when we receive a request in
-`proton::messaging_handler::on_message`, we look at the
-`proton::message::reply_to` address and create a sender with that
-address for the response. We'll cache the senders in case we get
-further requests with the same `reply_to`.
-
-Now let's create a simple @ref client.cpp to test this service out.
-
-\dontinclude client.cpp
-
-Our client takes a list of strings to send as requests.
-
-\skipline client(
-
-Since we will be sending and receiving, we create a sender and a
-receiver in `proton::messaging_handler::on_container_start`. Our
-receiver has a blank address and sets the `dynamic` flag to true,
-which means we expect the remote end (the broker or server) to assign
-a unique address for us.
-
-\skip on_container_start
-\until }
-
-Now we need a function to send the next request from our list of
-requests. We set the `reply_to` address to be the dynamically assigned
-address of our receiver.
-
-\skip send_request
-\until }
-
-We need to use the address assigned by the broker as the `reply_to`
-address of our requests, so we can't send them until our receiver has
-been set up. To do that, we add an
-`proton::messaging_handler::on_receiver_open()` method to our handler
-class and use that as the trigger to send our first request.
-
-\skip on_receiver_open
-\until }
-
-When we receive a reply, we send the next request.
-
-\skip on_message
-\until }
-\until }
-\until }
-
-Direct request and response
----------------------------
-
-We can avoid the intermediary process by writing a server that accepts
-connections directly, @ref server_direct.cpp. It involves the
-following changes to our original server:
-
-\dontinclude server_direct.cpp
-
-Our server must generate unique `reply-to` addresses for links from
-the client that request a dynamic address (previously this was done by
-the broker). We use a simple counter.
-
-\skip generate_address
-\until }
-
-Next we need to handle incoming requests for links with dynamic
-addresses from the client. We give the link a unique address and
-record it in our `senders` map.
-
-\skip on_sender_open
-\until }
-
-Note that we are interested in *sender* links above because we are
-implementing the server. A *receiver* link created on the client
-corresponds to a *sender* link on the server.
-
-Finally when we receive a message we look up its `reply_to` in our
-senders map and send the reply.
-
-\skip on_message
-\until }
-\until }
-\until }
-
-*/
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/exampletest.py
----------------------------------------------------------------------
diff --git a/examples/exampletest.py b/examples/exampletest.py
deleted file mode 100644
index d40b9cb..0000000
--- a/examples/exampletest.py
+++ /dev/null
@@ -1,183 +0,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
-#
-
-# A test library to make it easy to run unittest tests that start,
-# monitor, and report output from sub-processes. In particular
-# it helps with starting processes that listen on random ports.
-
-import unittest
-import os, sys, socket, time, re, inspect, errno, threading
-from random import randrange
-from subprocess import Popen, PIPE, STDOUT
-from copy import copy
-import platform
-from os.path import dirname as dirname
-
-def pick_port():
- """Pick a random port."""
- p = randrange(10000, 20000)
- return p
-
-class ProcError(Exception):
- """An exception that captures failed process output"""
- def __init__(self, proc, what="bad exit status"):
- out = proc.out.strip()
- if out:
- out = "\nvvvvvvvvvvvvvvvv\n%s\n^^^^^^^^^^^^^^^^\n" % out
- else:
- out = ", no output)"
- super(Exception, self, ).__init__(
- "%s %s, code=%s%s" % (proc.args, what, proc.returncode, out))
-
-class NotFoundError(ProcError):
- pass
-
-class Proc(Popen):
- """A example process that stores its output, optionally run with valgrind."""
-
- if "VALGRIND" in os.environ and os.environ["VALGRIND"]:
- env_args = [os.environ["VALGRIND"], "--error-exitcode=42", "--quiet", "--leak-check=full"]
- else:
- env_args = []
-
- @property
- def out(self):
- self._out.seek(0)
- return self._out.read()
-
- def __init__(self, args, **kwargs):
- """Start an example process"""
- args = list(args)
- self.args = args
- self._out = os.tmpfile()
- try:
- Popen.__init__(self, self.env_args + self.args, stdout=self._out, stderr=STDOUT, **kwargs)
- except OSError, e:
- if e.errno == errno.ENOENT:
- raise NotFoundError(self, str(e))
- raise ProcError(self, str(e))
- except Exception, e:
- raise ProcError(self, str(e))
-
- def kill(self):
- try:
- if self.poll() is None:
- Popen.kill(self)
- except:
- pass # Already exited.
- return self.out
-
- def wait_out(self, timeout=10, expect=0):
- """Wait for process to exit, return output. Raise ProcError on failure."""
- t = threading.Thread(target=self.wait)
- t.start()
- t.join(timeout)
- if self.poll() is None: # Still running
- self.kill()
- raise ProcError(self, "timeout")
- if expect is not None and self.poll() != expect:
- raise ProcError(self)
- return self.out
-
-# Work-around older python unittest that lacks setUpClass.
-if hasattr(unittest.TestCase, 'setUpClass') and hasattr(unittest.TestCase, 'tearDownClass'):
- TestCase = unittest.TestCase
-else:
- class TestCase(unittest.TestCase):
- """
- Roughly provides setUpClass and tearDownClass functionality for older python
- versions in our test scenarios. If subclasses override setUp or tearDown
- they *must* call the superclass.
- """
- def setUp(self):
- if not hasattr(type(self), '_setup_class_count'):
- type(self)._setup_class_count = len(
- inspect.getmembers(
- type(self),
- predicate=lambda(m): inspect.ismethod(m) and m.__name__.startswith('test_')))
- type(self).setUpClass()
-
- def tearDown(self):
- self.assertTrue(self._setup_class_count > 0)
- self._setup_class_count -= 1
- if self._setup_class_count == 0:
- type(self).tearDownClass()
-
-class ExampleTestCase(TestCase):
- """TestCase that manages started processes"""
- def setUp(self):
- super(ExampleTestCase, self).setUp()
- self.procs = []
-
- def tearDown(self):
- for p in self.procs:
- p.kill()
- super(ExampleTestCase, self).tearDown()
-
- def proc(self, *args, **kwargs):
- p = Proc(*args, **kwargs)
- self.procs.append(p)
- return p
-
-def wait_port(port, timeout=10):
- """Wait up to timeout for port to be connectable."""
- if timeout:
- deadline = time.time() + timeout
- while (timeout is None or time.time() < deadline):
- try:
- s = socket.create_connection((None, port), timeout) # Works for IPv6 and v4
- s.close()
- return
- except socket.error, e:
- if e.errno != errno.ECONNREFUSED: # Only retry on connection refused error.
- raise
- raise socket.timeout()
-
-
-class BrokerTestCase(ExampleTestCase):
- """
- ExampleTest that starts a broker in setUpClass and kills it in tearDownClass.
- Subclass must set `broker_exe` class variable with the name of the broker executable.
- """
-
- @classmethod
- def setUpClass(cls):
- cls.port = pick_port()
- cls.addr = "127.0.0.1:%s/examples" % (cls.port)
- cls.broker = None # In case Proc throws, create the attribute.
- cls.broker = Proc(cls.broker_exe + ["-a", cls.addr])
- try:
- wait_port(cls.port)
- except Exception, e:
- cls.broker.kill()
- raise ProcError(cls.broker, "timed out waiting for port")
-
- @classmethod
- def tearDownClass(cls):
- if cls.broker: cls.broker.kill()
-
- def tearDown(self):
- b = type(self).broker
- if b and b.poll() != None: # Broker crashed
- type(self).setUpClass() # Start another for the next test.
- raise ProcError(b, "broker crash")
- super(BrokerTestCase, self).tearDown()
-
-if __name__ == "__main__":
- unittest.main()
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
deleted file mode 100644
index c9aba01..0000000
--- a/examples/go/CMakeLists.txt
+++ /dev/null
@@ -1,54 +0,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.
-#
-
-if(BUILD_GO)
-
- set(examples electron/broker electron/receive electron/send proton/broker)
- file(GLOB_RECURSE example_source FOLLOW_SYMLINKS ${CMAKE_CURRENT_SOURCE_DIR}/*.go)
-
- # Build example exes
- foreach(example ${examples})
- string(REPLACE / _ target ${example})
- set(target "go_example_${target}")
- set(output ${CMAKE_CURRENT_BINARY_DIR}/${example})
- # Always run go_build, it will do nothing if there is nothing to do.
- # Otherwise it's too hard to get the dependencies right.
- add_custom_target(${target} ALL
- COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${output} ${CMAKE_CURRENT_SOURCE_DIR}/${example}.go
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
- DEPENDS go-build)
- list(APPEND example_targets ${target})
- endforeach()
-
- # Build test driver exe
- set(test_exe ${CMAKE_CURRENT_BINARY_DIR}/example_test)
- add_custom_target(go_example_test ALL
- COMMAND ${GO_TEST} -c -o ${test_exe} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.go
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
-
- add_test(
- NAME go-example-electron
- COMMAND ${GO_ENV} ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
-
- add_test(
- NAME go-example-proton
- COMMAND ${GO_ENV} ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
-
- list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
-endif()
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/go/README.md
----------------------------------------------------------------------
diff --git a/examples/go/README.md b/examples/go/README.md
deleted file mode 100644
index 24f4d2a..0000000
--- a/examples/go/README.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# Go examples
-
-## Electron examples
-
-[qpid.apache.org/electron](http://godoc.org/qpid.apache.org/electron) is a
-simple API for writing concurrent AMQP clients and servers.
-
-- [receive.go](electron/receive.go) receive from many connections concurrently.
-- [send.go](electron/send.go) send to many connections concurrently.
-- [broker.go](electron/broker.go) a simple broker using the electron API
-n
-## Proton examples
-
-[qpid.apache.org/proton](http://godoc.org/qpid.apache.org/proton) is an
-event-driven, concurrent-unsafe Go wrapper for the proton-C library. The
-[electron](http://godoc.org/qpid.apache.org/electron) package provides a more
-Go-friendly concurrent API built on top of proton.
-
-- [broker.go](proton/broker.go) a simple broker using the proton API
-
-See [A Tale of Two Brokers](#a-tale-of-two-brokers) for a comparison of the two APIs.
-
-## Using the Go packages
-
-If you have the proton-C library and headers installed you can get the latest go
-packages with
-
- go get qpid.apache.org/electron
-
-If Proton-C is installed in a non-standard place (other than /usr or /usr/local)
-you should set these environment variables before `go get`:
-
- export CGO_LDFLAGS="-L/<my-proton>/lib[64]"
- export CGO_CFLAGS="-I/<my-proton>/include"
- go get qpid.apache.org/electron
-
-If you have a proton build you don't need to `go get`, you can set your GOPATH
-to use the binding from the checkout with:
-
- source <path-to-proton>/config.sh
-
-Once you are set up, the go tools will work as normal. You can see documentation
-in your web browser at `localhost:6060` by running:
-
- godoc -http=:6060
-
-## Running the examples
-
-You can run the examples directly from source like this:
-
- go run <program>.go
-
-This is a little slow (a couple of seconds) as it compiles the program and runs it in one step.
-You can compile the program first and then run the executable to avoid the delay:
-
- go build <program>.go
- ./<program>
-
-All the examples take a `-h` flag to show usage information, and the comments in
-the example source have more details.
-
-First start the broker (the optional `-debug` flag will print extra information about
-what the broker is doing)
-
- go run broker.go -debug
-
-Send messages concurrently to queues "foo" and "bar", 10 messages to each queue:
-
- go run send.go -count 10 localhost:/foo localhost:/bar
-
-Receive messages concurrently from "foo" and "bar". Note -count 20 for 10 messages each on 2 queues:
-
- go run receive.go -count 20 localhost:/foo localhost:/bar
-
-The broker and clients use the standard AMQP port (5672) on the local host by
-default, to use a different address use the `-addr host:port` flag.
-
-If you have other Proton examples available you can try communicating between
-programs in in different languages. For example use the python broker with Go
-clients:
-
- python ../python/broker.py
- go run send.go -count 10 localhost:/foo localhost:/bar
-
-Or use the Go broker and the python clients:
-
- go run broker.go -debug
- python ../python/simple_send.py
- python ../python/simple_recv.py
-
-
-## A tale of two brokers.
-
-The [proton](http://godoc.org/qpid.apache.org/proton) and
-[electron](http://godoc.org/qpid.apache.org/electron) packages provide two
-different APIs for building AMQP applications. For most applications,
-[electron](http://godoc.org/qpid.apache.org/electron) is easier to use.
-[The proton Go README](https://github.com/apache/qpid-proton/blob/master/proton-c/bindings/go/src/qpid.apache.org/README.md)
-has some discussion about why there are two APIs.
-
-The examples [proton/broker.go](proton/broker.go) and
-[electron/broker.go](electron/broker.go) implement the same simple broker
-functionality using each of the two APIs. They both handle multiple connections
-concurrently and store messages on bounded queues implemented by Go channels.
-
-However the [electron/broker.go](electron/broker.go) is less than half as long as the
-[proton/broker.go](proton/broker.go) illustrating why it is better suited for most Go
-applications.
-
-[proton/broker.go](proton/broker.go) implements an event-driven loop per connection that reacts
-to events like 'incoming link', 'incoming message' and 'sender has credit'. It
-uses channels to exchange data between the event-loop goroutine for each
-connection and shared queues that are accessible to all connections. Sending
-messages is particularly tricky, the broker must monitor the queue for available
-messages and the sender link for available credit.
-
-
-[electron/broker.go](electron/broker.go) does not need any "upside-down"
-event-driven code, it is implemented as straightforward loops. The broker is a
-loop listening for connections. Each connection is a loop accepting for incoming
-sender or recdiver links. Each receiving link is a loop that receives a message
-and pushes it to a queue. Each sending link is a loop that pops a message from
-a queue and sends it.
-
-Queue bounds and credit manage themselves: popping from a queue blocks till
-there is a message, sending blocks until there is credit, receiving blocks till
-something is received and pushing onto a queue blocks until there is
-space. There's no need for code that monitors the state of multiple queues and
-links. Each loop has one simple job to do, and the Go run-time schedules them
-efficiently.
-
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/go/electron/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/broker.go b/examples/go/electron/broker.go
deleted file mode 100644
index d698838..0000000
--- a/examples/go/electron/broker.go
+++ /dev/null
@@ -1,204 +0,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.
-*/
-
-//
-// This is a simple AMQP broker implemented using the procedural electron package.
-//
-// It maintains a set of named in-memory queues of messages. Clients can send
-// messages to queues or subscribe to receive messages from them.
-//
-
-package main
-
-import (
- "../util"
- "flag"
- "fmt"
- "log"
- "net"
- "os"
- "qpid.apache.org/amqp"
- "qpid.apache.org/electron"
-)
-
-// Usage and command-line flags
-func usage() {
- fmt.Fprintf(os.Stderr, `
-Usage: %s
-A simple broker-like demo. Queues are created automatically for sender or receiver addrsses.
-`, os.Args[0])
- flag.PrintDefaults()
-}
-
-var addr = flag.String("addr", ":amqp", "Listening address")
-var credit = flag.Int("credit", 100, "Receiver credit window")
-var qsize = flag.Int("qsize", 1000, "Max queue size")
-
-func main() {
- flag.Usage = usage
- flag.Parse()
- b := &broker{
- queues: util.MakeQueues(*qsize),
- container: electron.NewContainer(fmt.Sprintf("broker[%s]", os.Getpid())),
- acks: make(chan electron.Outcome),
- sent: make(chan sentMessage),
- }
- if err := b.run(); err != nil {
- log.Fatal(err)
- }
-}
-
-// State for the broker
-type broker struct {
- queues util.Queues // A collection of queues.
- container electron.Container // electron.Container manages AMQP connections.
- sent chan sentMessage // Channel to record sent messages.
- acks chan electron.Outcome // Channel to receive the Outcome of sent messages.
-}
-
-// Record of a sent message and the queue it came from.
-// If a message is rejected or not acknowledged due to a failure, we will put it back on the queue.
-type sentMessage struct {
- m amqp.Message
- q util.Queue
-}
-
-// run listens for incoming net.Conn connections and starts an electron.Connection for each one.
-func (b *broker) run() error {
- listener, err := net.Listen("tcp", *addr)
- if err != nil {
- return err
- }
- defer listener.Close()
- fmt.Printf("Listening on %v\n", listener.Addr())
-
- go b.acknowledgements() // Handles acknowledgements for all connections.
-
- // Start a goroutine for each new connections
- for {
- c, err := b.container.Accept(listener)
- if err != nil {
- util.Debugf("Accept error: %v", err)
- continue
- }
- cc := &connection{b, c}
- go cc.run() // Handle the connection
- util.Debugf("Accepted %v", c)
- }
-}
-
-// State for a broker connectoin
-type connection struct {
- broker *broker
- connection electron.Connection
-}
-
-// accept remotely-opened endpoints (Session, Sender and Receiver) on a connection
-// and start goroutines to service them.
-func (c *connection) run() {
- for in := range c.connection.Incoming() {
- switch in := in.(type) {
-
- case *electron.IncomingSender:
- if in.Source() == "" {
- in.Reject(fmt.Errorf("no source"))
- } else {
- go c.sender(in.Accept().(electron.Sender))
- }
-
- case *electron.IncomingReceiver:
- if in.Target() == "" {
- in.Reject(fmt.Errorf("no target"))
- } else {
- in.SetPrefetch(true)
- in.SetCapacity(*credit) // Pre-fetch up to credit window.
- go c.receiver(in.Accept().(electron.Receiver))
- }
-
- default:
- in.Accept() // Accept sessions unconditionally
- }
- util.Debugf("incoming: %v", in)
- }
- util.Debugf("incoming closed: %v", c.connection)
-}
-
-// receiver receives messages and pushes to a queue.
-func (c *connection) receiver(receiver electron.Receiver) {
- q := c.broker.queues.Get(receiver.Target())
- for {
- if rm, err := receiver.Receive(); err == nil {
- util.Debugf("%v: received %v", receiver, util.FormatMessage(rm.Message))
- q <- rm.Message
- rm.Accept()
- } else {
- util.Debugf("%v error: %v", receiver, err)
- break
- }
- }
-}
-
-// sender pops messages from a queue and sends them.
-func (c *connection) sender(sender electron.Sender) {
- q := c.broker.queues.Get(sender.Source())
- for {
- if sender.Error() != nil {
- util.Debugf("%v closed: %v", sender, sender.Error())
- return
- }
- select {
-
- case m := <-q:
- util.Debugf("%v: sent %v", sender, util.FormatMessage(m))
- sm := sentMessage{m, q}
- c.broker.sent <- sm // Record sent message
- sender.SendAsync(m, c.broker.acks, sm) // Receive outcome on c.broker.acks with Value sm
-
- case <-sender.Done(): // break if sender is closed
- break
- }
- }
-}
-
-// acknowledgements keeps track of sent messages and receives outcomes.
-//
-// We could have handled outcomes separately per-connection, per-sender or even
-// per-message. Message outcomes are returned via channels defined by the user
-// so they can be grouped in any way that suits the application.
-func (b *broker) acknowledgements() {
- sentMap := make(map[sentMessage]bool)
- for {
- select {
- case sm, ok := <-b.sent: // A local sender records that it has sent a message.
- if ok {
- sentMap[sm] = true
- } else {
- return // Closed
- }
- case outcome := <-b.acks: // The message outcome is available
- sm := outcome.Value.(sentMessage)
- delete(sentMap, sm)
- if outcome.Status != electron.Accepted { // Error, release or rejection
- sm.q.PutBack(sm.m) // Put the message back on the queue.
- util.Debugf("message %v put back, status %v, error %v",
- util.FormatMessage(sm.m), outcome.Status, outcome.Error)
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/go/electron/receive.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/receive.go b/examples/go/electron/receive.go
deleted file mode 100644
index 7a505d8..0000000
--- a/examples/go/electron/receive.go
+++ /dev/null
@@ -1,112 +0,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.
-*/
-
-package main
-
-import (
- "../util"
- "flag"
- "fmt"
- "log"
- "os"
- "qpid.apache.org/amqp"
- "qpid.apache.org/electron"
- "sync"
-)
-
-// Usage and command-line flags
-func usage() {
- fmt.Fprintf(os.Stderr, `Usage: %s url [url ...]
-Receive messages from all the listed URLs concurrently and print them.
-`, os.Args[0])
- flag.PrintDefaults()
-}
-
-var count = flag.Uint64("count", 1, "Stop after receiving this many messages.")
-
-func main() {
- flag.Usage = usage
- flag.Parse()
-
- urls := flag.Args() // Non-flag arguments are URLs to receive from
- if len(urls) == 0 {
- log.Println("No URL provided")
- usage()
- os.Exit(1)
- }
-
- messages := make(chan amqp.Message) // Channel for messages from goroutines to main()
- defer close(messages)
-
- var wait sync.WaitGroup // Used by main() to wait for all goroutines to end.
- wait.Add(len(urls)) // Wait for one goroutine per URL.
-
- container := electron.NewContainer(fmt.Sprintf("receive[%s]", os.Getpid()))
- connections := make(chan electron.Connection, len(urls)) // Connections to close on exit
-
- // Start a goroutine to for each URL to receive messages and send them to the messages channel.
- // main() receives and prints them.
- for _, urlStr := range urls {
- util.Debugf("Connecting to %s\n", urlStr)
- go func(urlStr string) { // Start the goroutine
-
- defer wait.Done() // Notify main() when this goroutine is done.
- url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.
- util.ExitIf(err)
-
- // Open a new connection
- c, err := container.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
- util.ExitIf(err)
- connections <- c // Save connection so we can Close() when main() ends
-
- // Create a Receiver using the path of the URL as the source address
- r, err := c.Receiver(electron.Source(url.Path))
- util.ExitIf(err)
-
- // Loop receiving messages and sending them to the main() goroutine
- for {
- if rm, err := r.Receive(); err != nil {
- util.Debugf("closed %v: %v", urlStr, err)
- return
- } else {
- rm.Accept()
- messages <- rm.Message
- }
- }
- }(urlStr)
- }
-
- // All goroutines are started, we are receiving messages.
- fmt.Printf("Listening on %d connections\n", len(urls))
-
- // print each message until the count is exceeded.
- for i := uint64(0); i < *count; i++ {
- m := <-messages
- util.Debugf("%s\n", util.FormatMessage(m))
- }
- fmt.Printf("Received %d messages\n", *count)
-
- // Close all connections, this will interrupt goroutines blocked in Receiver.Receive()
- for i := 0; i < len(urls); i++ {
- c := <-connections
- util.Debugf("close %s", c)
- c.Close(nil)
- }
- wait.Wait() // Wait for all goroutines to finish.
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/go/electron/send.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/send.go b/examples/go/electron/send.go
deleted file mode 100644
index 4ea93ec..0000000
--- a/examples/go/electron/send.go
+++ /dev/null
@@ -1,110 +0,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.
-*/
-
-package main
-
-import (
- "../util"
- "flag"
- "fmt"
- "log"
- "os"
- "qpid.apache.org/amqp"
- "qpid.apache.org/electron"
- "sync"
-)
-
-// Usage and command-line flags
-func usage() {
- fmt.Fprintf(os.Stderr, `Usage: %s url [url ...]
-Send messages to each URL concurrently with body "<url-path>-<n>" where n is the message number.
-`, os.Args[0])
- flag.PrintDefaults()
-}
-
-var count = flag.Int64("count", 1, "Send this may messages per address.")
-
-func main() {
- flag.Usage = usage
- flag.Parse()
-
- urls := flag.Args() // Non-flag arguments are URLs to receive from
- if len(urls) == 0 {
- log.Println("No URL provided")
- flag.Usage()
- os.Exit(1)
- }
-
- sentChan := make(chan electron.Outcome) // Channel to receive acknowledgements.
-
- var wait sync.WaitGroup
- wait.Add(len(urls)) // Wait for one goroutine per URL.
-
- container := electron.NewContainer(fmt.Sprintf("send[%s]", os.Getpid()))
- connections := make(chan electron.Connection, len(urls)) // Connctions to close on exit
-
- // Start a goroutine for each URL to send messages.
- for _, urlStr := range urls {
- util.Debugf("Connecting to %v\n", urlStr)
- go func(urlStr string) {
-
- defer wait.Done() // Notify main() that this goroutine is done.
- url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.
- util.ExitIf(err)
-
- // Open a new connection
- c, err := container.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
- util.ExitIf(err)
- connections <- c // Save connection so we can Close() when main() ends
-
- // Create a Sender using the path of the URL as the AMQP address
- s, err := c.Sender(electron.Target(url.Path))
- util.ExitIf(err)
-
- // Loop sending messages.
- for i := int64(0); i < *count; i++ {
- m := amqp.NewMessage()
- body := fmt.Sprintf("%v-%v", url.Path, i)
- m.Marshal(body)
- s.SendAsync(m, sentChan, body) // Outcome will be sent to sentChan
- }
- }(urlStr)
- }
-
- // Wait for all the acknowledgements
- expect := int(*count) * len(urls)
- util.Debugf("Started senders, expect %v acknowledgements\n", expect)
- for i := 0; i < expect; i++ {
- out := <-sentChan // Outcome of async sends.
- if out.Error != nil {
- util.Debugf("acknowledgement[%v] %v error: %v\n", i, out.Value, out.Error)
- } else {
- util.Debugf("acknowledgement[%v] %v (%v)\n", i, out.Value, out.Status)
- }
- }
- fmt.Printf("Received all %v acknowledgements\n", expect)
-
- wait.Wait() // Wait for all goroutines to finish.
- close(connections)
- for c := range connections { // Close all connections
- if c != nil {
- c.Close(nil)
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/go/example_test.go
----------------------------------------------------------------------
diff --git a/examples/go/example_test.go b/examples/go/example_test.go
deleted file mode 100644
index 6de309e..0000000
--- a/examples/go/example_test.go
+++ /dev/null
@@ -1,274 +0,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.
-*/
-
-// Tests to verify that example code behaves as expected.
-// Run in this directory with `go test example_test.go`
-//
-package main
-
-import (
- "bufio"
- "bytes"
- "flag"
- "fmt"
- "io"
- "log"
- "math/rand"
- "net"
- "os"
- "os/exec"
- "path"
- "path/filepath"
- "reflect"
- "testing"
- "time"
-)
-
-func fatalIf(t *testing.T, err error) {
- if err != nil {
- t.Fatalf("%s", err)
- }
-}
-
-// A demo broker process
-type broker struct {
- cmd *exec.Cmd
- addr string
- runerr chan error
- err error
-}
-
-// Try to connect to the broker to verify it is ready, give up after a timeout
-func (b *broker) check() error {
- dialer := net.Dialer{Deadline: time.Now().Add(time.Second * 10)}
- for {
- c, err := dialer.Dial("tcp", b.addr)
- if err == nil { // Success
- c.Close()
- return nil
- }
- select {
- case runerr := <-b.runerr: // Broker exited.
- return runerr
- default:
- }
- if neterr, ok := err.(net.Error); ok && neterr.Timeout() { // Running but timed out
- b.stop()
- return fmt.Errorf("timed out waiting for broker")
- }
- time.Sleep(time.Second / 10)
- }
-}
-
-// Start the demo broker, wait till it is listening on *addr. No-op if already started.
-func (b *broker) start(t *testing.T) error {
- if b.cmd == nil { // Not already started
- b.addr = fmt.Sprintf("127.0.0.1:%d", rand.Intn(10000)+10000)
- b.cmd = exampleCommand(t, *brokerName, "-addr", b.addr)
- b.runerr = make(chan error)
- b.cmd.Stderr, b.cmd.Stdout = os.Stderr, os.Stdout
- b.err = b.cmd.Start()
- if b.err == nil {
- go func() { b.runerr <- b.cmd.Wait() }()
- } else {
- b.runerr <- b.err
- }
- b.err = b.check()
- }
- return b.err
-}
-
-func (b *broker) stop() {
- if b != nil && b.cmd != nil {
- b.cmd.Process.Kill()
- <-b.runerr
- }
-}
-
-func checkEqual(want interface{}, got interface{}) error {
- if reflect.DeepEqual(want, got) {
- return nil
- }
- return fmt.Errorf("%#v != %#v", want, got)
-}
-
-// exampleCommand returns an exec.Cmd to run an example.
-func exampleCommand(t *testing.T, prog string, arg ...string) (cmd *exec.Cmd) {
- args := []string{}
- if *debug {
- args = append(args, "-debug=true")
- }
- args = append(args, arg...)
- prog, err := filepath.Abs(path.Join(*dir, prog))
- fatalIf(t, err)
- if _, err := os.Stat(prog); err == nil {
- cmd = exec.Command(prog, args...)
- } else if _, err := os.Stat(prog + ".go"); err == nil {
- args = append([]string{"run", prog + ".go"}, args...)
- cmd = exec.Command("go", args...)
- } else {
- t.Fatalf("Cannot find binary or source for %s", prog)
- }
- cmd.Stderr = os.Stderr
- return cmd
-}
-
-// Run an example Go program, return the combined output as a string.
-func runExample(t *testing.T, prog string, arg ...string) (string, error) {
- cmd := exampleCommand(t, prog, arg...)
- out, err := cmd.Output()
- return string(out), err
-}
-
-func prefix(prefix string, err error) error {
- if err != nil {
- return fmt.Errorf("%s: %s", prefix, err)
- }
- return nil
-}
-
-func runExampleWant(t *testing.T, want string, prog string, args ...string) error {
- out, err := runExample(t, prog, args...)
- if err != nil {
- return fmt.Errorf("%s failed: %s: %s", prog, err, out)
- }
- return prefix(prog, checkEqual(want, out))
-}
-
-func exampleArgs(args ...string) []string {
- for i := 0; i < *connections; i++ {
- args = append(args, fmt.Sprintf("%s/%s%d", testBroker.addr, "q", i))
- }
- return args
-}
-
-// Send then receive
-func TestExampleSendReceive(t *testing.T) {
- if testing.Short() {
- t.Skip("Skip demo tests in short mode")
- }
- testBroker.start(t)
- err := runExampleWant(t,
- fmt.Sprintf("Received all %d acknowledgements\n", expected),
- "send",
- exampleArgs("-count", fmt.Sprintf("%d", *count))...)
- if err != nil {
- t.Fatal(err)
- }
- err = runExampleWant(t,
- fmt.Sprintf("Listening on %v connections\nReceived %v messages\n", *connections, *count**connections),
- "receive",
- exampleArgs("-count", fmt.Sprintf("%d", *count**connections))...)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-var ready error
-
-func init() { ready = fmt.Errorf("Ready") }
-
-// Run receive in a goroutine.
-// Send ready on errchan when it is listening.
-// Send final error when it is done.
-// Returns the Cmd, caller must Wait()
-func goReceiveWant(t *testing.T, errchan chan<- error, want string, arg ...string) *exec.Cmd {
- cmd := exampleCommand(t, "receive", arg...)
- go func() {
- pipe, err := cmd.StdoutPipe()
- if err != nil {
- errchan <- err
- return
- }
- out := bufio.NewReader(pipe)
- cmd.Start()
- line, err := out.ReadString('\n')
- if err != nil && err != io.EOF {
- errchan <- err
- return
- }
- listening := "Listening on 3 connections\n"
- if line != listening {
- errchan <- checkEqual(listening, line)
- return
- }
- errchan <- ready
- buf := bytes.Buffer{}
- io.Copy(&buf, out) // Collect the rest of the output
- cmd.Wait()
- errchan <- checkEqual(want, buf.String())
- close(errchan)
- }()
- return cmd
-}
-
-// Start receiver first, wait till it is running, then send.
-func TestExampleReceiveSend(t *testing.T) {
- if testing.Short() {
- t.Skip("Skip demo tests in short mode")
- }
- testBroker.start(t)
-
- // Start receiver, wait for "listening" message on stdout
- recvCmd := exampleCommand(t, "receive", exampleArgs(fmt.Sprintf("-count=%d", expected))...)
- pipe, err := recvCmd.StdoutPipe()
- if err != nil {
- t.Fatal(err)
- }
- recvCmd.Start()
- out := bufio.NewReader(pipe)
- line, err := out.ReadString('\n')
- if err := checkEqual("Listening on 3 connections\n", line); err != nil {
- t.Fatal(err)
- }
-
- if err := runExampleWant(t,
- fmt.Sprintf("Received all %d acknowledgements\n", expected),
- "send",
- exampleArgs("-count", fmt.Sprintf("%d", *count))...); err != nil {
- t.Fatal(err)
- }
-
- buf := bytes.Buffer{}
- io.Copy(&buf, out)
- if err := checkEqual(fmt.Sprintf("Received %d messages\n", expected), buf.String()); err != nil {
- t.Fatal(err)
- }
-}
-
-var testBroker *broker
-
-var debug = flag.Bool("debug", false, "Debugging output from examples")
-var brokerName = flag.String("broker", "broker", "Name of broker executable to run")
-var count = flag.Int("count", 3, "Count of messages to send in tests")
-var connections = flag.Int("connections", 3, "Number of connections to make in tests")
-var dir = flag.String("dir", "electron", "Directory containing example sources or binaries")
-var expected int
-
-func TestMain(m *testing.M) {
- if out, err := exec.Command("go", "install", "qpid.apache.org/...").CombinedOutput(); err != nil {
- log.Fatalf("go install failed: %s\n%s", err, out)
- }
- expected = (*count) * (*connections)
- rand.Seed(time.Now().UTC().UnixNano())
- testBroker = &broker{} // Broker is started on-demand by tests.
- status := m.Run()
- testBroker.stop()
- os.Exit(status)
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org