http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/c/reactor/sender.c ---------------------------------------------------------------------- diff --git a/examples/c/reactor/sender.c b/examples/c/reactor/sender.c deleted file mode 100644 index 6c3cdb3..0000000 --- a/examples/c/reactor/sender.c +++ /dev/null @@ -1,329 +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 <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "pncompat/misc_funcs.inc" - -#include "proton/reactor.h" -#include "proton/message.h" -#include "proton/connection.h" -#include "proton/session.h" -#include "proton/link.h" -#include "proton/delivery.h" -#include "proton/event.h" -#include "proton/handlers.h" -#include "proton/transport.h" -#include "proton/url.h" - - -static int quiet = 0; - -// Example application data. This data will be instantiated in the event -// handler, and is available during event processing. In this example it -// holds configuration and state information. -// -typedef struct { - int count; // # messages to send - int anon; // use anonymous link if true - const char *target; // name of destination target - char *msg_data; // pre-encoded outbound message - size_t msg_len; // bytes in msg_data -} app_data_t; - -// helper to pull pointer to app_data_t instance out of the pn_handler_t -// -#define GET_APP_DATA(handler) ((app_data_t *)pn_handler_mem(handler)) - -// Called when reactor exits to clean up app_data -// -static void delete_handler(pn_handler_t *handler) -{ - app_data_t *d = GET_APP_DATA(handler); - if (d->msg_data) { - free(d->msg_data); - d->msg_data = NULL; - } -} - -/* Process each event posted by the reactor. - */ -static void event_handler(pn_handler_t *handler, - pn_event_t *event, - pn_event_type_t type) -{ - app_data_t *data = GET_APP_DATA(handler); - - switch (type) { - - case PN_CONNECTION_INIT: { - // Create and open all the endpoints needed to send a message - // - pn_connection_t *conn; - pn_session_t *ssn; - pn_link_t *sender; - - conn = pn_event_connection(event); - pn_connection_open(conn); - ssn = pn_session(conn); - pn_session_open(ssn); - sender = pn_sender(ssn, "MySender"); - // we do not wait for ack until the last message - pn_link_set_snd_settle_mode(sender, PN_SND_MIXED); - if (!data->anon) { - pn_terminus_set_address(pn_link_target(sender), data->target); - } - pn_link_open(sender); - } break; - - case PN_LINK_FLOW: { - // the remote has given us some credit, now we can send messages - // - static long tag = 0; // a simple tag generator - pn_delivery_t *delivery; - pn_link_t *sender = pn_event_link(event); - int credit = pn_link_credit(sender); - while (credit > 0 && data->count > 0) { - --credit; - --data->count; - ++tag; - delivery = pn_delivery(sender, - pn_dtag((const char *)&tag, sizeof(tag))); - pn_link_send(sender, data->msg_data, data->msg_len); - pn_link_advance(sender); - if (data->count > 0) { - // send pre-settled until the last one, then wait for an ack on - // the last sent message. This allows the sender to send - // messages as fast as possible and then exit when the consumer - // has dealt with the last one. - // - pn_delivery_settle(delivery); - } - } - } break; - - case PN_DELIVERY: { - // Since the example sends all messages but the last pre-settled - // (pre-acked), only the last message's delivery will get updated with - // the remote state (acked/nacked). - // - pn_delivery_t *dlv = pn_event_delivery(event); - if (pn_delivery_updated(dlv) && pn_delivery_remote_state(dlv)) { - uint64_t rs = pn_delivery_remote_state(dlv); - int done = 1; - switch (rs) { - case PN_RECEIVED: - // This is not a terminal state - it is informational, and the - // peer is still processing the message. - done = 0; - break; - case PN_ACCEPTED: - pn_delivery_settle(dlv); - if (!quiet) fprintf(stdout, "Send complete!\n"); - break; - case PN_REJECTED: - case PN_RELEASED: - case PN_MODIFIED: - pn_delivery_settle(dlv); - fprintf(stderr, "Message not accepted - code:%lu\n", (unsigned long)rs); - break; - default: - // ??? no other terminal states defined, so ignore anything else - pn_delivery_settle(dlv); - fprintf(stderr, "Unknown delivery failure - code=%lu\n", (unsigned long)rs); - break; - } - - if (done) { - // initiate clean shutdown of the endpoints - pn_link_t *link = pn_delivery_link(dlv); - pn_session_t *ssn = pn_link_session(link); - pn_link_close(link); - pn_session_close(ssn); - pn_connection_close(pn_session_connection(ssn)); - } - } - } break; - - case PN_TRANSPORT_ERROR: { - // The connection to the peer failed. - // - pn_transport_t *tport = pn_event_transport(event); - pn_condition_t *cond = pn_transport_condition(tport); - fprintf(stderr, "Network transport failed!\n"); - if (pn_condition_is_set(cond)) { - const char *name = pn_condition_get_name(cond); - const char *desc = pn_condition_get_description(cond); - fprintf(stderr, " Error: %s Description: %s\n", - (name) ? name : "<error name not provided>", - (desc) ? desc : "<no description provided>"); - } - // pn_reactor_process() will exit with a false return value, stopping - // the main loop. - } break; - - default: - break; - } -} - -static void usage(void) -{ - printf("Usage: send <options> <message>\n"); - printf("-a \tThe host address [localhost:5672]\n"); - printf("-c \t# of messages to send [1]\n"); - printf("-t \tTarget address [examples]\n"); - printf("-n \tUse an anonymous link [off]\n"); - printf("-i \tContainer name [SendExample]\n"); - printf("-q \tQuiet - turn off stdout\n"); - printf("message \tA text string to send.\n"); - exit(1); -} - -int main(int argc, char** argv) -{ - const char *address = "localhost"; - const char *msgtext = "Hello World!"; - const char *container = "SendExample"; - int c; - pn_message_t *message = NULL; - pn_data_t *body = NULL; - pn_reactor_t *reactor = NULL; - pn_url_t *url = NULL; - pn_connection_t *conn = NULL; - - /* Create a handler for the connection's events. event_handler() will be - * called for each event and delete_handler will be called when the - * connection is released. The handler will allocate an app_data_t - * instance which can be accessed when the event_handler is called. - */ - pn_handler_t *handler = pn_handler_new(event_handler, - sizeof(app_data_t), - delete_handler); - - /* set up the application data with defaults */ - app_data_t *app_data = GET_APP_DATA(handler); - memset(app_data, 0, sizeof(app_data_t)); - app_data->count = 1; - app_data->target = "examples"; - - /* Attach the pn_handshaker() handler. This handler deals with endpoint - * events from the peer so we don't have to. - */ - { - pn_handler_t *handshaker = pn_handshaker(); - pn_handler_add(handler, handshaker); - pn_decref(handshaker); - } - - /* command line options */ - opterr = 0; - while((c = getopt(argc, argv, "i:a:c:t:nhq")) != -1) { - switch(c) { - case 'h': usage(); break; - case 'a': address = optarg; break; - case 'c': - app_data->count = atoi(optarg); - if (app_data->count < 1) usage(); - break; - case 't': app_data->target = optarg; break; - case 'n': app_data->anon = 1; break; - case 'i': container = optarg; break; - case 'q': quiet = 1; break; - default: - usage(); - break; - } - } - if (optind < argc) msgtext = argv[optind]; - - - // create a single message and pre-encode it so we only have to do that - // once. All transmits will use the same pre-encoded message simply for - // speed. - // - message = pn_message(); - pn_message_set_address(message, app_data->target); - body = pn_message_body(message); - pn_data_clear(body); - - // This message's body contains a single string - if (pn_data_fill(body, "S", msgtext)) { - fprintf(stderr, "Error building message!\n"); - exit(1); - } - pn_data_rewind(body); - { - // encode the message, expanding the encode buffer as needed - // - size_t len = 128; - char *buf = (char *)malloc(len); - int rc = 0; - do { - rc = pn_message_encode(message, buf, &len); - if (rc == PN_OVERFLOW) { - free(buf); - len *= 2; - buf = (char *)malloc(len); - } - } while (rc == PN_OVERFLOW); - app_data->msg_len = len; - app_data->msg_data = buf; - } - pn_decref(message); // message no longer needed - - reactor = pn_reactor(); - - url = pn_url_parse(address); - if (url == NULL) { - fprintf(stderr, "Invalid host address %s\n", address); - exit(1); - } - conn = pn_reactor_connection_to_host(reactor, - pn_url_get_host(url), - pn_url_get_port(url), - handler); - pn_decref(url); - pn_decref(handler); - - // the container name should be unique for each client - pn_connection_set_container(conn, container); - - // wait up to 5 seconds for activity before returning from - // pn_reactor_process() - pn_reactor_set_timeout(reactor, 5000); - - pn_reactor_start(reactor); - - while (pn_reactor_process(reactor)) { - /* Returns 'true' until the connection is shut down. - * pn_reactor_process() will return true at least once every 5 seconds - * (due to the timeout). If no timeout was configured, - * pn_reactor_process() returns as soon as it finishes processing all - * pending I/O and events. Once the connection has closed, - * pn_reactor_process() will return false. - */ - } - pn_decref(reactor); - - return 0; -}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt deleted file mode 100644 index 304d899..0000000 --- a/examples/cpp/CMakeLists.txt +++ /dev/null @@ -1,83 +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. -# - -find_package(ProtonCpp REQUIRED) - -include_directories(${ProtonCpp_INCLUDE_DIRS}) -link_libraries(${ProtonCpp_LIBRARIES}) -add_definitions(${CXX_WARNING_FLAGS}) - -# Add a test with the correct environment to find test executables and valgrind. -macro(add_cpp_test name) - if(WIN32) - set(test_path "$<TARGET_FILE_DIR:broker>;$<TARGET_FILE_DIR:qpid-proton>;$<TARGET_FILE_DIR:qpid-proton-cpp>") - else(WIN32) - set(test_path "$<TARGET_FILE_DIR:broker>:$ENV{PATH}") - endif(WIN32) - set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py) - add_test(NAME ${name} COMMAND ${run_env} "PATH=${test_path}" ${VALGRIND_ENV} -- ${ARGN}) -endmacro() - -# Single-threaded examples that work on C++03 -foreach(example - broker - helloworld - helloworld_direct - simple_recv - simple_send - scheduled_send_03 - direct_recv - direct_send - client - server - server_direct - connection_options - queue_browser - selected_recv - flow_control - ssl - ssl_client_cert - service_bus - encode_decode) - add_executable(${example} ${example}.cpp) -endforeach() - -if(HAS_CPP11) - # Single-threaded examples that require C++11 - foreach(example - scheduled_send) - add_executable(${example} ${example}.cpp) - endforeach() - - # Linux-only multi-threaded examples (TODO make these portable) -# if(CMAKE_SYSTEM_NAME STREQUAL "Linux") -# set(container_src mt/epoll_container.cpp) -# foreach(example -# broker) -# add_executable(mt_${example} mt/${example}.cpp ${container_src}) -# target_link_libraries(mt_${example} pthread) -# endforeach() -# add_cpp_test(cpp-example-mt ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v MtBrokerTest) -# endif() -endif() - -add_cpp_test(cpp-example-container ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v ContainerExampleTest) - - - http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/README.dox ---------------------------------------------------------------------- diff --git a/examples/cpp/README.dox b/examples/cpp/README.dox deleted file mode 100644 index 447d3ad..0000000 --- a/examples/cpp/README.dox +++ /dev/null @@ -1,163 +0,0 @@ -// C++ examples list (doxygen format) -// -// For a tutorial-style description of the examples see tutorial.dox. -// To build the full HTML tutorial and documentation, in your build directory do: -// -// make docs-cpp -// -// then open proton-c/bindings/cpp/docs/html/tutorial.html in your browser. - -// DEVELOPER NOTE: if you add or modify examples, please add/update a short -// description below and (if appropriate) extend/update tutorial.dox. - -/** example sub directory - -The example sub-directory has utilities classes to make the example simpler, -these classes are not directly related to the use of proton so are in a separate -`example` directory and namespace. - -*/ - -/** @example helloworld.cpp - -Connects to a broker on 127.0.0.1:5672, establishes a subscription -from the 'examples' node, and creates a sending link to the same -node. Sends one message and receives it back. - -*/ - -/** @example helloworld_direct.cpp - -Variation of helloworld that does not use a broker, but listens for -incoming connections itself. It establishes a connection to itself -with a link over which a single message is sent. This demonstrates the -ease with which a simple daemon an be built using the API. - -*/ - -/** @example simple_send.cpp - -An example of sending a fixed number of messages and tracking their -(asynchronous) acknowledgement. Messages are sent through the 'examples' node on -an intermediary accessible on 127.0.0.1:5672. - -*/ - -/** @example simple_recv.cpp - -Subscribes to the 'examples' node on an intermediary accessible -on 127.0.0.1:5672. Simply prints out the body of received messages. - -*/ - -/** @example direct_send.cpp - -Accepts an incoming connection and then sends like `simple_send`. You can -connect directly to `direct_send` *without* a broker using @ref simple_recv.cpp. -Make sure to stop the broker first or use a different port for `direct_send`. - -*/ - -/** @example direct_recv.cpp - -Accepts an incoming connection and then receives like `simple_recv`. You can -connect directly to `direct_recv` *without* a broker using @ref simple_send.cpp. -Make sure to stop the broker first or use a different port for `direct_recv`. - -*/ - -/// @cond INTERNAL -/** @example encode_decode.cpp - -Shows how C++ data types can be converted to and from AMQP types. - -*/ -/// @endcond - -/** @example client.cpp - -The client part of a request-response example. Sends requests and -prints out responses. Requires an intermediary that supports the AMQP -1.0 dynamic nodes on which the responses are received. The requests -are sent through the 'examples' node. - -*/ - -/** @example server.cpp - -The server part of a request-response example, that receives requests -via the examples node, converts the body to uppercase and sends the -result back to the indicated reply address. - -*/ - -/** @example server_direct.cpp - -A variant of the server part of a request-response example that -accepts incoming connections and does not need an intermediary. Much -like the original server, it receives incoming requests, converts the -body to uppercase and sends the result back to the indicated reply -address. Can be used in conjunction with any of the client -alternatives. - -*/ - -/** @example broker.hpp - -Common logic for a simple "mini broker" that creates creates queues -automatically when a client tries to send or subscribe. This file contains -the `queue` class that queues messages and the `broker_handler` class -that manages queues and links and transfers messages to/from clients. - -*/ - -/** @example broker.cpp - -A simple, single-threaded broker using the `proton::container`. You can use this -to run other examples that reqiure an intermediary, or you can use any AMQP 1.0 -broker. This broker creates queues automatically when a client tries to send or -subscribe. - -*/ - -/** @example mt/epoll_container.cpp - -An example implementation of the proton::container API that shows how -to use the proton::io::connection_driver SPI to adapt the proton API -to native IO, in this case using a multithreaded Linux epoll poller as -the implementation. - -__Requires C++11__ - -*/ - -/** @example mt/broker.cpp - -A multithreaded broker, that will work on any multi-threaded container. See @ref mt/epoll_container.cpp for an example of a multi-threaded container. - -__Requires C++11__ - -*/ - -/** @example scheduled_send.cpp - -Shows how to use proton::container::schedule to schedule a timed callback. -This version uses std::function and so requires C++11 or better. For a C++03 compatible -approach see @ref scheduled_send_03.cpp. - -*/ - -/** @example scheduled_send_03.cpp - -Shows how to use proton::container::schedule to schedule a timed callback in a -C++03 compatible way. See @ref scheduled_send.cpp for a more convenient approach -using std::function if you have C++11. - -*/ - -/** @example service_bus.cpp - -A working example for accessing Service Bus session-enabled queues. -Also provides some general notes on Service Bus usage. - -*/ http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/broker.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp deleted file mode 100644 index 97ef206..0000000 --- a/examples/cpp/broker.cpp +++ /dev/null @@ -1,286 +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.hpp> -#include <proton/container.hpp> -#include <proton/default_container.hpp> -#include <proton/delivery.hpp> -#include <proton/error_condition.hpp> -#include <proton/listener.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/message.hpp> -#include <proton/receiver_options.hpp> -#include <proton/sender.hpp> -#include <proton/sender_options.hpp> -#include <proton/source_options.hpp> -#include <proton/target_options.hpp> -#include <proton/tracker.hpp> -#include <proton/transport.hpp> -#include <proton/url.hpp> - -#include <deque> -#include <iostream> -#include <list> -#include <map> -#include <string> - -#include "fake_cpp11.hpp" - -/// A simple implementation of a queue. -class queue { - public: - queue(const std::string &name, bool dynamic = false) : name_(name), dynamic_(dynamic) {} - - std::string name() const { return name_; } - - void subscribe(proton::sender s) { - consumers_.push_back(s); - } - - // Return true if queue can be deleted. - bool unsubscribe(proton::sender s) { - consumers_.remove(s); - return (consumers_.size() == 0 && (dynamic_ || messages_.size() == 0)); - } - - void publish(const proton::message &m) { - messages_.push_back(m); - dispatch(0); - } - - void dispatch(proton::sender *s) { - while (deliver_to(s)) {} - } - - bool deliver_to(proton::sender *s) { - // Deliver to single sender if supplied, else all consumers - int count = s ? 1 : consumers_.size(); - - if (!count) return false; - - bool result = false; - sender_list::iterator it = consumers_.begin(); - - if (!s && count) { - s = &*it; - } - - while (messages_.size()) { - if (s->credit()) { - const proton::message& m = messages_.front(); - - s->send(m); - messages_.pop_front(); - result = true; - } - - if (--count) { - it++; - } else { - return result; - } - } - - return false; - } - - private: - typedef std::deque<proton::message> message_queue; - typedef std::list<proton::sender> sender_list; - - std::string name_; - bool dynamic_; - message_queue messages_; - sender_list consumers_; -}; - -/// A collection of queues and queue factory, used by a broker. -class queues { - public: - queues() : next_id_(0) {} - virtual ~queues() {} - - // Get or create a queue. - virtual queue &get(const std::string &address) { - if (address.empty()) { - throw std::runtime_error("empty queue name"); - } - - queue*& q = queues_[address]; - - if (!q) q = new queue(address); - - return *q; - } - - // Create a dynamic queue with a unique name. - virtual queue &dynamic() { - std::ostringstream os; - os << "q" << next_id_++; - queue *q = queues_[os.str()] = new queue(os.str(), true); - - return *q; - } - - // Delete the named queue - virtual void erase(std::string &name) { - delete queues_[name]; - queues_.erase(name); - } - - protected: - typedef std::map<std::string, queue *> queue_map; - queue_map queues_; - int next_id_; // Use to generate unique queue IDs. -}; - -// A handler to implement broker logic -class broker_handler : public proton::messaging_handler { - public: - broker_handler(queues& qs) : queues_(qs) {} - - void on_sender_open(proton::sender &sender) OVERRIDE { - proton::source src(sender.source()); - queue *q; - if (src.dynamic()) { - q = &queues_.dynamic(); - } else if (!src.address().empty()) { - q = &queues_.get(src.address()); - } else { - sender.close(proton::error_condition("No queue address supplied")); - return; - } - sender.open(proton::sender_options().source(proton::source_options().address(q->name()))); - q->subscribe(sender); - std::cout << "broker outgoing link from " << q->name() << std::endl; - } - - void on_receiver_open(proton::receiver &receiver) OVERRIDE { - std::string address = receiver.target().address(); - if (!address.empty()) { - receiver.open(proton::receiver_options().target(proton::target_options().address(address))); - std::cout << "broker incoming link to " << address << std::endl; - } else { - receiver.close(proton::error_condition("No queue address supplied")); - } - } - - void unsubscribe(proton::sender lnk) { - std::string address = lnk.source().address(); - - if (queues_.get(address).unsubscribe(lnk)) { - queues_.erase(address); - } - } - - void on_sender_close(proton::sender &sender) OVERRIDE { - unsubscribe(sender); - } - - void on_connection_close(proton::connection &c) OVERRIDE { - remove_stale_consumers(c); - } - - void on_transport_close(proton::transport &t) OVERRIDE { - remove_stale_consumers(t.connection()); - } - - void on_transport_error(proton::transport &t) OVERRIDE { - std::cout << "broker client disconnect: " << t.error().what() << std::endl; - } - - void on_error(const proton::error_condition &c) OVERRIDE { - std::cerr << "broker error: " << c.what() << std::endl; - } - - void remove_stale_consumers(proton::connection connection) { - proton::sender_range r = connection.senders(); - for (proton::sender_iterator i = r.begin(); i != r.end(); ++i) { - if (i->active()) - unsubscribe(*i); - } - } - - void on_sendable(proton::sender &s) OVERRIDE { - std::string address = s.source().address(); - - queues_.get(address).dispatch(&s); - } - - void on_message(proton::delivery &d, proton::message &m) OVERRIDE { - std::string address = d.receiver().target().address(); - queues_.get(address).publish(m); - } - - protected: - queues& queues_; -}; - - -// The broker -class broker { - public: - broker(const std::string& url) : handler_(url, queues_) {} - - proton::messaging_handler& handler() { return handler_; } - - private: - class my_handler : public broker_handler { - public: - my_handler(const std::string& u, queues& qs) : broker_handler(qs), url_(u) {} - - void on_container_start(proton::container &c) OVERRIDE { - c.listen(url_); - std::cout << "broker listening on " << url_ << std::endl; - } - - private: - const std::string& url_; - }; - - private: - queues queues_; - my_handler handler_; -}; - -int main(int argc, char **argv) { - std::string url("0.0.0.0"); - example::options opts(argc, argv); - - opts.add_value(url, 'a', "address", "listen on URL", "URL"); - - try { - opts.parse(); - - broker b(url); - proton::default_container(b.handler()).run(); - - return 0; - } catch (const example::bad_option& e) { - std::cout << opts << std::endl << e.what() << std::endl; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - - return 1; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/broker.hpp ---------------------------------------------------------------------- diff --git a/examples/cpp/broker.hpp b/examples/cpp/broker.hpp deleted file mode 100644 index 953713f..0000000 --- a/examples/cpp/broker.hpp +++ /dev/null @@ -1,236 +0,0 @@ -#ifndef BROKER_HPP -#define BROKER_HPP - -/* - * 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. - */ - -/// @file -/// -/// Common code used by different broker examples. -/// -/// The examples add functionality as needed, this helps to make it -/// easier to see the important differences between the examples. - -#include <proton/connection.hpp> -#include <proton/delivery.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/message.hpp> -#include <proton/sasl.hpp> -#include <proton/sender.hpp> -#include <proton/tracker.hpp> -#include <proton/transport.hpp> -#include <proton/sender_options.hpp> -#include <proton/receiver_options.hpp> -#include <proton/source_options.hpp> -#include <proton/target_options.hpp> - -#include <iostream> -#include <deque> -#include <map> -#include <list> -#include <sstream> - -/// A simple implementation of a queue. -class queue { - public: - queue(const std::string &name, bool dynamic = false) : name_(name), dynamic_(dynamic) {} - - std::string name() const { return name_; } - - void subscribe(proton::sender s) { - consumers_.push_back(s); - } - - // Return true if queue can be deleted. - bool unsubscribe(proton::sender s) { - consumers_.remove(s); - return (consumers_.size() == 0 && (dynamic_ || messages_.size() == 0)); - } - - void publish(const proton::message &m) { - messages_.push_back(m); - dispatch(0); - } - - void dispatch(proton::sender *s) { - while (deliver_to(s)) {} - } - - bool deliver_to(proton::sender *s) { - // Deliver to single sender if supplied, else all consumers - int count = s ? 1 : consumers_.size(); - - if (!count) return false; - - bool result = false; - sender_list::iterator it = consumers_.begin(); - - if (!s && count) { - s = &*it; - } - - while (messages_.size()) { - if (s->credit()) { - const proton::message& m = messages_.front(); - - s->send(m); - messages_.pop_front(); - result = true; - } - - if (--count) { - it++; - } else { - return result; - } - } - - return false; - } - - private: - typedef std::deque<proton::message> message_queue; - typedef std::list<proton::sender> sender_list; - - std::string name_; - bool dynamic_; - message_queue messages_; - sender_list consumers_; -}; - -/// A collection of queues and queue factory, used by a broker. -class queues { - public: - queues() : next_id_(0) {} - virtual ~queues() {} - - // Get or create a queue. - virtual queue &get(const std::string &address = std::string()) { - if (address.empty()) { - throw std::runtime_error("empty queue name"); - } - - queue*& q = queues_[address]; - - if (!q) q = new queue(address); - - return *q; - } - - // Create a dynamic queue with a unique name. - virtual queue &dynamic() { - std::ostringstream os; - os << "q" << next_id_++; - queue *q = queues_[os.str()] = new queue(os.str(), true); - - return *q; - } - - // Delete the named queue - virtual void erase(std::string &name) { - delete queues_[name]; - queues_.erase(name); - } - - protected: - typedef std::map<std::string, queue *> queue_map; - queue_map queues_; - int next_id_; // Use to generate unique queue IDs. -}; - -#include <proton/config.hpp> - -/** Common handler logic for brokers. */ -class broker_handler : public proton::messaging_handler { - public: - broker_handler(queues& qs) : queues_(qs) {} - - void on_transport_open(proton::transport &t) OVERRIDE { - std::cout << "Connection from user: " << t.sasl().user() << " (mechanism: " << t.sasl().mech() << ")" << std::endl; - } - - void on_sender_open(proton::sender &sender) OVERRIDE { - proton::source src(sender.source()); - queue &q = src.dynamic() ? - queues_.dynamic() : queues_.get(src.address()); - sender.open(proton::sender_options().source(proton::source_options().address(q.name()))); - q.subscribe(sender); - std::cout << "broker outgoing link from " << q.name() << std::endl; - } - - void on_receiver_open(proton::receiver &receiver) OVERRIDE { - std::string address = receiver.target().address(); - if (!address.empty()) { - receiver.open(proton::receiver_options().target(proton::target_options().address(address))); - std::cout << "broker incoming link to " << address << std::endl; - } - } - - void unsubscribe(proton::sender lnk) { - std::string address = lnk.source().address(); - - if (queues_.get(address).unsubscribe(lnk)) { - queues_.erase(address); - } - } - - void on_sender_close(proton::sender &sender) OVERRIDE { - unsubscribe(sender); - } - - void on_connection_close(proton::connection &c) OVERRIDE { - remove_stale_consumers(c); - } - - void on_transport_close(proton::transport &t) OVERRIDE { - remove_stale_consumers(t.connection()); - } - - void on_transport_error(proton::transport &t) OVERRIDE { - std::cout << "broker client disconnect: " << t.error().what() << std::endl; - } - - void on_error(const proton::error_condition &c) OVERRIDE { - std::cerr << "broker error: " << c.what() << std::endl; - } - - void remove_stale_consumers(proton::connection connection) { - proton::sender_range sr = connection.senders(); - for (proton::sender_iterator i = sr.begin(); i != sr.end(); ++i) { - if (i->active()) - unsubscribe(*i); - } - } - - void on_sendable(proton::sender &s) OVERRIDE { - std::string address = s.source().address(); - - queues_.get(address).dispatch(&s); - } - - void on_message(proton::delivery &d, proton::message &m) OVERRIDE { - std::string address = d.receiver().target().address(); - queues_.get(address).publish(m); - } - - protected: - queues& queues_; -}; - -#endif // BROKER_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/client.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp deleted file mode 100644 index 7139155..0000000 --- a/examples/cpp/client.cpp +++ /dev/null @@ -1,111 +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.hpp> -#include <proton/container.hpp> -#include <proton/default_container.hpp> -#include <proton/delivery.hpp> -#include <proton/message.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/receiver_options.hpp> -#include <proton/source_options.hpp> -#include <proton/thread_safe.hpp> -#include <proton/tracker.hpp> - -#include <iostream> -#include <vector> - -#include "fake_cpp11.hpp" - -using proton::receiver_options; -using proton::source_options; - -class client : public proton::messaging_handler { - private: - std::string url; - std::vector<std::string> requests; - proton::sender sender; - proton::receiver receiver; - - public: - client(const std::string &u, const std::vector<std::string>& r) : url(u), requests(r) {} - - void on_container_start(proton::container &c) OVERRIDE { - sender = c.open_sender(url); - // Create a receiver requesting a dynamically created queue - // for the message source. - receiver_options opts = receiver_options().source(source_options().dynamic(true)); - receiver = sender.connection().open_receiver("", opts); - } - - void send_request() { - proton::message req; - req.body(requests.front()); - req.reply_to(receiver.source().address()); - sender.send(req); - } - - void on_receiver_open(proton::receiver &) OVERRIDE { - send_request(); - } - - void on_message(proton::delivery &d, proton::message &response) OVERRIDE { - if (requests.empty()) return; // Spurious extra message! - - std::cout << requests.front() << " => " << response.body() << std::endl; - requests.erase(requests.begin()); - - if (!requests.empty()) { - send_request(); - } else { - d.connection().close(); - } - } -}; - -int main(int argc, char **argv) { - std::string url("127.0.0.1:5672/examples"); - example::options opts(argc, argv); - - opts.add_value(url, 'a', "address", "connect and send to URL", "URL"); - - try { - opts.parse(); - - std::vector<std::string> requests; - requests.push_back("Twas brillig, and the slithy toves"); - requests.push_back("Did gire and gymble in the wabe."); - requests.push_back("All mimsy were the borogroves,"); - requests.push_back("And the mome raths outgrabe."); - - client c(url, requests); - proton::default_container(c).run(); - - return 0; - } catch (const example::bad_option& e) { - std::cout << opts << std::endl << e.what() << std::endl; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - - return 1; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/connection_options.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/connection_options.cpp b/examples/cpp/connection_options.cpp deleted file mode 100644 index f718060..0000000 --- a/examples/cpp/connection_options.cpp +++ /dev/null @@ -1,78 +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/messaging_handler.hpp> -#include <proton/thread_safe.hpp> -#include <proton/transport.hpp> - -#include <iostream> - -using proton::connection_options; - -#include "fake_cpp11.hpp" - -class handler_2 : public proton::messaging_handler { - void on_connection_open(proton::connection &c) OVERRIDE { - std::cout << "connection events going to handler_2" << std::endl; - std::cout << "connection max_frame_size: " << c.max_frame_size() << - ", idle timeout: " << c.idle_timeout() << std::endl; - c.close(); - } -}; - -class main_handler : public proton::messaging_handler { - private: - std::string url; - handler_2 conn_handler; - - public: - main_handler(const std::string& u) : url(u) {} - - void on_container_start(proton::container &c) OVERRIDE { - // Connection options for this connection. Merged with and overriding the container's - // client_connection_options() settings. - c.connect(url, connection_options().handler(conn_handler).max_frame_size(2468)); - } - - void on_connection_open(proton::connection &c) OVERRIDE { - std::cout << "unexpected connection event on main handler" << std::endl; - c.close(); - } -}; - -int main(int argc, char **argv) { - try { - std::string url = argc > 1 ? argv[1] : "127.0.0.1:5672/examples"; - main_handler handler(url); - proton::default_container container(handler); - // Global connection options for future connections on container. - container.client_connection_options(connection_options().max_frame_size(12345).idle_timeout(proton::duration(15000))); - container.run(); - return 0; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - return 1; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/direct_recv.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp deleted file mode 100644 index 705b480..0000000 --- a/examples/cpp/direct_recv.cpp +++ /dev/null @@ -1,95 +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.hpp> -#include <proton/container.hpp> -#include <proton/default_container.hpp> -#include <proton/delivery.hpp> -#include <proton/message.hpp> -#include <proton/message_id.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/link.hpp> -#include <proton/listener.hpp> -#include <proton/value.hpp> - -#include <iostream> -#include <map> - -#include "fake_cpp11.hpp" - -class direct_recv : public proton::messaging_handler { - private: - std::string url; - proton::listener listener; - int expected; - int received; - - public: - direct_recv(const std::string &s, int c) : url(s), expected(c), received(0) {} - - void on_container_start(proton::container &c) OVERRIDE { - listener = c.listen(url); - std::cout << "direct_recv listening on " << url << std::endl; - } - - void on_message(proton::delivery &d, proton::message &msg) OVERRIDE { - if (proton::coerce<int>(msg.id()) < received) { - return; // Ignore duplicate - } - - if (expected == 0 || received < expected) { - std::cout << msg.body() << std::endl; - received++; - } - - if (received == expected) { - d.receiver().close(); - d.connection().close(); - listener.stop(); - } - } -}; - -int main(int argc, char **argv) { - std::string address("127.0.0.1:5672/examples"); - int message_count = 100; - example::options opts(argc, argv); - - opts.add_value(address, 'a', "address", "listen and receive on URL", "URL"); - opts.add_value(message_count, 'm', "messages", "receive COUNT messages", "COUNT"); - - try { - opts.parse(); - - direct_recv recv(address, message_count); - proton::default_container(recv).run(); - - return 0; - } catch (const example::bad_option& e) { - std::cout << opts << std::endl << e.what() << std::endl; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - - return 1; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/direct_send.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp deleted file mode 100644 index 7de762d..0000000 --- a/examples/cpp/direct_send.cpp +++ /dev/null @@ -1,106 +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.hpp> -#include <proton/container.hpp> -#include <proton/default_container.hpp> -#include <proton/listener.hpp> -#include <proton/message.hpp> -#include <proton/message_id.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/value.hpp> -#include <proton/tracker.hpp> -#include <proton/types.hpp> - -#include <iostream> -#include <map> - -#include "fake_cpp11.hpp" - -class simple_send : public proton::messaging_handler { - private: - std::string url; - proton::listener listener; - int sent; - int confirmed; - int total; - - public: - simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {} - - void on_container_start(proton::container &c) OVERRIDE { - listener = c.listen(url); - std::cout << "direct_send listening on " << url << std::endl; - } - - void on_sendable(proton::sender &sender) OVERRIDE { - while (sender.credit() && sent < total) { - proton::message msg; - std::map<std::string, int> m; - m["sequence"] = sent + 1; - - msg.id(sent + 1); - msg.body(m); - - sender.send(msg); - sent++; - } - } - - void on_tracker_accept(proton::tracker &t) OVERRIDE { - confirmed++; - - if (confirmed == total) { - std::cout << "all messages confirmed" << std::endl; - t.connection().close(); - listener.stop(); - } - } - - void on_transport_close(proton::transport &) OVERRIDE { - sent = confirmed; - } -}; - -int main(int argc, char **argv) { - std::string address("127.0.0.1:5672/examples"); - int message_count = 100; - example::options opts(argc, argv); - - opts.add_value(address, 'a', "address", "listen and send on URL", "URL"); - opts.add_value(message_count, 'm', "messages", "send COUNT messages", "COUNT"); - - try { - opts.parse(); - - simple_send send(address, message_count); - proton::default_container(send).run(); - return 0; - } catch (const example::bad_option& e) { - std::cout << opts << std::endl << e.what() << std::endl; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - - return 1; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/encode_decode.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp deleted file mode 100644 index 862d1dd..0000000 --- a/examples/cpp/encode_decode.cpp +++ /dev/null @@ -1,251 +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/types.hpp> -#include <proton/codec/encoder.hpp> -#include <proton/codec/decoder.hpp> - -#include <algorithm> -#include <iostream> -#include <iterator> -#include <sstream> - -// Examples of how to use the encoder and decoder to create and examine AMQP values. -// - -// Print is defined at the end as an example of how to query and extract complex -// values from a decoder in terms of their simple components. -void print(proton::value&); - -// Some helper templates to print map and std::vector results. -namespace std { -template<class T, class U> ostream& operator<<(ostream& o, const std::pair<T,U>& p) { - return o << p.first << ":" << p.second; -} -template<class T> ostream& operator<<(ostream& o, const std::vector<T>& v) { - o << "[ "; - ostream_iterator<T> oi(o, " "); - copy(v.begin(), v.end(), oi); - return o << "]"; -} -template<class T> ostream& operator<<(ostream& o, const std::list<T>& v) { - o << "[ "; - ostream_iterator<T> oi(o, " "); - copy(v.begin(), v.end(), oi); - return o << "]"; -} -template<class K, class T> ostream& operator<<(ostream& o, const map<K, T>& m) { - o << "{ "; - ostream_iterator<std::pair<K,T> > oi(o, " "); - copy(m.begin(), m.end(), oi); - return o << "}"; -} -} - -// Insert/extract native C++ containers with uniform type values. -static void uniform_containers() { - std::cout << std::endl << "== Array, list and map of uniform type." << std::endl; - proton::value v; - - std::vector<int> a; - a.push_back(1); - a.push_back(2); - a.push_back(3); - // By default a C++ container is encoded as an AMQP array. - v = a; - print(v); - std::list<int> a1; - proton::get(v, a1); - std::cout << a1 << std::endl; - - // You can specify that a container should be encoded as an AMQP list instead. - v = proton::codec::encoder::list(a1); - print(v); - std::cout << proton::get<std::vector<int> >(v) << std::endl; - - // C++ map types (types with key_type, mapped_type) convert to an AMQP map by default. - std::map<std::string, int> m; - m["one"] = 1; - m["two"] = 2; - v = m; - print(v); - std::cout << proton::get<std::map<std::string, int> >(v) << std::endl; - - // A sequence of pairs encodes as an AMQP MAP, which lets you control the encoded order. - std::vector<std::pair<std::string, int> > pairs; - pairs.push_back(std::make_pair("z", 3)); - pairs.push_back(std::make_pair("a", 4)); - v = pairs; - print(v); - - // You can also decode an AMQP map as a sequence of pairs to preserve encode order. - std::vector<std::pair<std::string, int> > pairs2; - proton::codec::decoder d(v); - d >> pairs2; - std::cout << pairs2 << std::endl; - - // A vector of proton::value is normally encoded as a mixed-type AMQP LIST, - // but you can encoded it as an array provided all the values match the array type. - std::vector<proton::value> vv; - vv.push_back(proton::value("a")); - vv.push_back(proton::value("b")); - vv.push_back(proton::value("c")); - v = vv; - print(v); -} - -// Containers with mixed types use value to represent arbitrary AMQP types. -static void mixed_containers() { - std::cout << std::endl << "== List and map of mixed type values." << std::endl; - proton::value v; - - std::vector<proton::value> l; - l.push_back(proton::value(42)); - l.push_back(proton::value(std::string("foo"))); - // By default, a sequence of proton::value is treated as an AMQP list. - v = l; - print(v); - std::vector<proton::value> l2 = proton::get<std::vector<proton::value> >(v); - std::cout << l2 << std::endl; - - std::map<proton::value, proton::value> m; - m[proton::value("five")] = proton::value(5); - m[proton::value(4)] = proton::value("four"); v = m; - print(v); - typedef std::map<proton::value, proton::value> value_map; - value_map m2(proton::get<value_map>(v)); - std::cout << m2 << std::endl; -} - -// Insert using stream operators (see print_next for example of extracting with stream ops.) -static void insert_stream_operators() { - std::cout << std::endl << "== Insert with stream operators." << std::endl; - proton::value v; - - // Create an array of INT with values [1, 2, 3] - proton::codec::encoder e(v); - e << proton::codec::start::array(proton::INT) - << int32_t(1) << int32_t(2) << int32_t(3) - << proton::codec::finish(); - print(v); - - // Create a mixed-type list of the values [42, 0, "x"]. - proton::codec::encoder e2(v); - e2 << proton::codec::start::list() - << int32_t(42) << false << proton::symbol("x") - << proton::codec::finish(); - print(v); - - // Create a map { "k1":42, "k2": false } - proton::codec::encoder e3(v); - e3 << proton::codec::start::map() - << "k1" << int32_t(42) - << proton::symbol("k2") << false - << proton::codec::finish(); - print(v); -} - -int main(int, char**) { - try { - uniform_containers(); - mixed_containers(); - insert_stream_operators(); - return 0; - } catch (const std::exception& e) { - std::cerr << std::endl << "error: " << e.what() << std::endl; - } - return 1; -} - -// print_next prints the next value from values by recursively descending into complex values. -// -// NOTE this is for example puroses only: There is a built in ostream operator<< for values. -// -// -static void print_next(proton::codec::decoder& d) { - proton::type_id type = d.next_type(); - proton::codec::start s; - switch (type) { - case proton::ARRAY: { - d >> s; - std::cout << "array<" << s.element; - if (s.is_described) { - std::cout << ", descriptor="; - print_next(d); - } - std::cout << ">["; - for (size_t i = 0; i < s.size; ++i) { - if (i) std::cout << ", "; - print_next(d); - } - std::cout << "]"; - d >> proton::codec::finish(); - break; - } - case proton::LIST: { - d >> s; - std::cout << "list["; - for (size_t i = 0; i < s.size; ++i) { - if (i) std::cout << ", "; - print_next(d); - } - std::cout << "]"; - d >> proton::codec::finish(); - break; - } - case proton::MAP: { - d >> s; - std::cout << "map{"; - for (size_t i = 0; i < s.size/2; ++i) { - if (i) std::cout << ", "; - print_next(d); - std::cout << ":"; // key:value - print_next(d); - } - std::cout << "}"; - d >> proton::codec::finish(); - break; - } - case proton::DESCRIBED: { - d >> s; - std::cout << "described("; - print_next(d); // Descriptor - print_next(d); // value - d >> proton::codec::finish(); - break; - } - default: - // A simple type. We could continue the switch for all AMQP types but - // we will take a short cut and extract to another value and print that. - proton::value v2; - d >> v2; - std::cout << type << "(" << v2 << ")"; - } -} - -// Print a value, for example purposes. Normal code can use operator<< -void print(proton::value& v) { - proton::codec::decoder d(v); - d.rewind(); - while (d.more()) { - print_next(d); - if (d.more()) std::cout << ", "; - } - std::cout << std::endl; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/example_test.py ---------------------------------------------------------------------- diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py deleted file mode 100644 index e2052dc..0000000 --- a/examples/cpp/example_test.py +++ /dev/null @@ -1,451 +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 test script to run the examples and verify that they behave as expected. - -import unittest -import os, sys, socket, time, re, inspect -from random import randrange -from subprocess import Popen, PIPE, STDOUT, call -from copy import copy -import platform -from os.path import dirname as dirname -from threading import Thread, Event -from string import Template - -createdSASLDb = False - -def findfileinpath(filename, searchpath): - """Find filename in the searchpath - return absolute path to the file or None - """ - paths = searchpath.split(os.pathsep) - for path in paths: - if os.path.exists(os.path.join(path, filename)): - return os.path.abspath(os.path.join(path, filename)) - return None - -def _cyrusSetup(conf_dir): - """Write out simple SASL config. - """ - saslpasswd = "" - if 'SASLPASSWD' in os.environ: - saslpasswd = os.environ['SASLPASSWD'] - else: - saslpasswd = findfileinpath('saslpasswd2', os.getenv('PATH')) or "" - if os.path.exists(saslpasswd): - t = Template("""sasldb_path: ${db} -mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS -""") - abs_conf_dir = os.path.abspath(conf_dir) - call(args=['rm','-rf',abs_conf_dir]) - os.mkdir(abs_conf_dir) - db = os.path.join(abs_conf_dir,'proton.sasldb') - conf = os.path.join(abs_conf_dir,'proton-server.conf') - f = open(conf, 'w') - f.write(t.substitute(db=db)) - f.close() - - cmd_template = Template("echo password | ${saslpasswd} -c -p -f ${db} -u proton user") - cmd = cmd_template.substitute(db=db, saslpasswd=saslpasswd) - call(args=cmd, shell=True) - - os.environ['PN_SASL_CONFIG_PATH'] = abs_conf_dir - global createdSASLDb - createdSASLDb = True - -# Globally initialize Cyrus SASL configuration -#if SASL.extended(): -_cyrusSetup('sasl_conf') - -def ensureCanTestExtendedSASL(): -# if not SASL.extended(): -# raise Skipped('Extended SASL not supported') - if not createdSASLDb: - raise Skipped("Can't Test Extended SASL: Couldn't create auth db") - -def pick_addr(): - """Pick a new host:port address.""" - # TODO Conway 2015-07-14: need a safer way to pick ports. - p = randrange(10000, 20000) - return "127.0.0.1:%s" % p - -class ProcError(Exception): - """An exception that captures failed process output""" - def __init__(self, proc, what="non-0 exit"): - 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 Proc(Popen): - """A example process that stores its stdout and can scan it for a 'ready' pattern'""" - - if "VALGRIND" in os.environ and os.environ["VALGRIND"]: - env_args = [os.environ["VALGRIND"], "--error-exitcode=42", "--quiet", "--leak-check=full"] - else: - env_args = [] - - def __init__(self, args, ready=None, timeout=30, skip_valgrind=False, **kwargs): - """Start an example process""" - args = list(args) - if platform.system() == "Windows": - args[0] += ".exe" - self.timeout = timeout - self.args = args - self.out = "" - if not skip_valgrind: - args = self.env_args + args - try: - Popen.__init__(self, args, stdout=PIPE, stderr=STDOUT, - universal_newlines=True, **kwargs) - except Exception as e: - raise ProcError(self, str(e)) - # Start reader thread. - self.pattern = ready - self.ready = Event() - # Help with Python 2.5, 2.6, 2.7 changes to Event.wait(), Event.is_set - self.ready_set = False - self.error = None - self.thread = Thread(target=self.run_) - self.thread.daemon = True - self.thread.start() - if self.pattern: - self.wait_ready() - - def run_(self): - try: - while True: - l = self.stdout.readline() - if not l: break - self.out += l - if self.pattern is not None: - if re.search(self.pattern, l): - self.ready_set = True - self.ready.set() - if self.wait() != 0: - raise ProcError(self) - except Exception as e: - self.error = e - finally: - self.stdout.close() - self.ready_set = True - self.ready.set() - - def safe_kill(self): - """Kill and clean up zombie but don't wait forever. No exceptions.""" - try: - self.kill() - self.thread.join(self.timeout) - except: pass - return self.out - - def check_(self): - if self.error: - raise self.error - - def wait_ready(self): - """Wait for ready to appear in output""" - self.ready.wait(self.timeout) - if self.ready_set: - self.check_() - return self.out - else: - self.safe_kill() - raise ProcError(self, "timeout waiting for '%s'" % self.pattern) - - def wait_exit(self): - """Wait for process to exit, return output. Raise ProcError on failure.""" - self.thread.join(self.timeout) - if self.poll() is not None: - self.check_() - return self.out - else: - raise ProcError(self, "timeout waiting for exit") - - -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.safe_kill() - super(ExampleTestCase, self).tearDown() - - def proc(self, *args, **kwargs): - p = Proc(*args, **kwargs) - self.procs.append(p) - return p - -class BrokerTestCase(ExampleTestCase): - """ - ExampleTest that starts a broker in setUpClass and kills it in tearDownClass. - Subclasses must set `broker_exe` class variable with the name of the broker executable. - """ - - @classmethod - def setUpClass(cls): - cls.addr = pick_addr() + "/examples" - cls.broker = None # In case Proc throws, create the attribute. - cls.broker = Proc([cls.broker_exe, "-a", cls.addr], ready="listening") - cls.broker.wait_ready() - - @classmethod - def tearDownClass(cls): - if cls.broker: cls.broker.safe_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() - - -CLIENT_EXPECT="""Twas brillig, and the slithy toves => TWAS BRILLIG, AND THE SLITHY TOVES -Did gire and gymble in the wabe. => DID GIRE AND GYMBLE IN THE WABE. -All mimsy were the borogroves, => ALL MIMSY WERE THE BOROGROVES, -And the mome raths outgrabe. => AND THE MOME RATHS OUTGRABE. -""" - -def recv_expect(name, addr): - return "%s listening on %s\n%s" % ( - name, addr, "".join(['{"sequence"=%s}\n' % (i+1) for i in range(100)])) - -class ContainerExampleTest(BrokerTestCase): - """Run the container examples, verify they behave as expected.""" - - broker_exe = "broker" - - def test_helloworld(self): - self.assertEqual('Hello World!\n', self.proc(["helloworld", self.addr]).wait_exit()) - - def test_helloworld_direct(self): - self.assertEqual('Hello World!\n', self.proc(["helloworld_direct", pick_addr()]).wait_exit()) - - def test_simple_send_recv(self): - self.assertEqual("all messages confirmed\n", - self.proc(["simple_send", "-a", self.addr]).wait_exit()) - self.assertEqual(recv_expect("simple_recv", self.addr), self.proc(["simple_recv", "-a", self.addr]).wait_exit()) - - def test_simple_recv_send(self): - # Start receiver first, then run sender""" - recv = self.proc(["simple_recv", "-a", self.addr]) - self.assertEqual("all messages confirmed\n", - self.proc(["simple_send", "-a", self.addr]).wait_exit()) - self.assertEqual(recv_expect("simple_recv", self.addr), recv.wait_exit()) - - - def test_simple_send_direct_recv(self): - addr = pick_addr() - recv = self.proc(["direct_recv", "-a", addr], "listening") - self.assertEqual("all messages confirmed\n", - self.proc(["simple_send", "-a", addr]).wait_exit()) - self.assertEqual(recv_expect("direct_recv", addr), recv.wait_exit()) - - def test_simple_recv_direct_send(self): - addr = pick_addr() - send = self.proc(["direct_send", "-a", addr], "listening") - self.assertEqual(recv_expect("simple_recv", addr), - self.proc(["simple_recv", "-a", addr]).wait_exit()) - - self.assertEqual( - "direct_send listening on %s\nall messages confirmed\n" % addr, - send.wait_exit()) - - def test_request_response(self): - server = self.proc(["server", "-a", self.addr], "connected") - self.assertEqual(CLIENT_EXPECT, - self.proc(["client", "-a", self.addr]).wait_exit()) - - def test_request_response_direct(self): - addr = pick_addr() - server = self.proc(["server_direct", "-a", addr+"/examples"], "listening") - self.assertEqual(CLIENT_EXPECT, - self.proc(["client", "-a", addr+"/examples"]).wait_exit()) - - def test_flow_control(self): - want="""success: Example 1: simple credit -success: Example 2: basic drain -success: Example 3: drain without credit -success: Exmaple 4: high/low watermark -""" - self.assertEqual(want, self.proc(["flow_control", "--address", pick_addr(), "--quiet"]).wait_exit()) - - def test_encode_decode(self): - want=""" -== Array, list and map of uniform type. -array<int>[int(1), int(2), int(3)] -[ 1 2 3 ] -list[int(1), int(2), int(3)] -[ 1 2 3 ] -map{string(one):int(1), string(two):int(2)} -{ one:1 two:2 } -map{string(z):int(3), string(a):int(4)} -[ z:3 a:4 ] -list[string(a), string(b), string(c)] - -== List and map of mixed type values. -list[int(42), string(foo)] -[ 42 foo ] -map{int(4):string(four), string(five):int(5)} -{ 4:four five:5 } - -== Insert with stream operators. -array<int>[int(1), int(2), int(3)] -list[int(42), boolean(0), symbol(x)] -map{string(k1):int(42), symbol(k2):boolean(0)} -""" - self.maxDiff = None - self.assertEqual(want, self.proc(["encode_decode"]).wait_exit()) - - def ssl_certs_dir(self): - """Absolute path to the test SSL certificates""" - pn_root = dirname(dirname(dirname(sys.argv[0]))) - return os.path.join(pn_root, "examples/cpp/ssl_certs") - - def test_ssl(self): - # SSL without SASL, VERIFY_PEER_NAME - addr = "amqps://" + pick_addr() + "/examples" - # Disable valgrind when using OpenSSL - out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir()], skip_valgrind=True).wait_exit() - expect = "Outgoing client connection connected via SSL. Server certificate identity CN=test_server\nHello World!" - expect_found = (out.find(expect) >= 0) - self.assertEqual(expect_found, True) - - def test_ssl_no_name(self): - # VERIFY_PEER - addr = "amqps://" + pick_addr() + "/examples" - # Disable valgrind when using OpenSSL - out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir(), "-v", "noname"], skip_valgrind=True).wait_exit() - expect = "Outgoing client connection connected via SSL. Server certificate identity CN=test_server\nHello World!" - expect_found = (out.find(expect) >= 0) - self.assertEqual(expect_found, True) - - def test_ssl_bad_name(self): - # VERIFY_PEER - addr = "amqps://" + pick_addr() + "/examples" - # Disable valgrind when using OpenSSL - out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir(), "-v", "fail"], skip_valgrind=True).wait_exit() - expect = "Expected failure of connection with wrong peer name" - expect_found = (out.find(expect) >= 0) - self.assertEqual(expect_found, True) - - def test_ssl_client_cert(self): - # SSL with SASL EXTERNAL - expect="""Inbound client certificate identity CN=test_client -Outgoing client connection connected via SSL. Server certificate identity CN=test_server -Hello World! -""" - addr = "amqps://" + pick_addr() + "/examples" - # Disable valgrind when using OpenSSL - out = self.proc(["ssl_client_cert", addr, self.ssl_certs_dir()], skip_valgrind=True).wait_exit() - expect_found = (out.find(expect) >= 0) - self.assertEqual(expect_found, True) - - def test_scheduled_send_03(self): - # Output should be a bunch of "send" lines but can't guarantee exactly how many. - out = self.proc(["scheduled_send_03", "-a", self.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).wait_exit().split() - self.assertTrue(len(out) > 0); - self.assertEqual(["send"]*len(out), out) - - def test_scheduled_send(self): - try: - out = self.proc(["scheduled_send", "-a", self.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).wait_exit().split() - self.assertTrue(len(out) > 0); - self.assertEqual(["send"]*len(out), out) - except ProcError: # File not found, not a C++11 build. - pass - - -class EngineTestCase(BrokerTestCase): - """Run selected clients to test a connction_engine broker.""" - - def test_helloworld(self): - self.assertEqual('Hello World!\n', - self.proc(["helloworld", self.addr]).wait_exit()) - - def test_simple_send_recv(self): - self.assertEqual("all messages confirmed\n", - self.proc(["simple_send", "-a", self.addr]).wait_exit()) - self.assertEqual(recv_expect("simple_recv", self.addr), self.proc(["simple_recv", "-a", self.addr]).wait_exit()) - - def test_simple_recv_send(self): - # Start receiver first, then run sender""" - recv = self.proc(["simple_recv", "-a", self.addr]) - self.assertEqual("all messages confirmed\n", self.proc(["simple_send", "-a", self.addr]).wait_exit()) - self.assertEqual(recv_expect("simple_recv", self.addr), recv.wait_exit()) - - - def test_simple_send_direct_recv(self): - addr = pick_addr() - recv = self.proc(["direct_recv", "-a", addr], "listening") - self.assertEqual("all messages confirmed\n", - self.proc(["simple_send", "-a", addr]).wait_exit()) - self.assertEqual(recv_expect("direct_recv", addr), recv.wait_exit()) - - def test_simple_recv_direct_send(self): - addr = pick_addr() - send = self.proc(["direct_send", "-a", addr], "listening") - self.assertEqual(recv_expect("simple_recv", addr), - self.proc(["simple_recv", "-a", addr]).wait_exit()) - self.assertEqual("direct_send listening on %s\nall messages confirmed\n" % addr, - send.wait_exit()) - - def test_request_response(self): - server = self.proc(["server", "-a", self.addr], "connected") - self.assertEqual(CLIENT_EXPECT, - self.proc(["client", "-a", self.addr]).wait_exit()) - - -class MtBrokerTest(EngineTestCase): - broker_exe = "mt_broker" - -if __name__ == "__main__": - unittest.main() http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/fake_cpp11.hpp ---------------------------------------------------------------------- diff --git a/examples/cpp/fake_cpp11.hpp b/examples/cpp/fake_cpp11.hpp deleted file mode 100644 index 03daa3b..0000000 --- a/examples/cpp/fake_cpp11.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef FAKE_CPP11_HPP -#define FAKE_CPP11_HPP - -/* - * 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. - */ - -/// These definitions allow us to use some new C++11 features in previous compilers -/// -/// It is strongly recommended not to copy this - just use C++11/C++14 instead! - -#if __cplusplus < 201103L -#define OVERRIDE -#else -#define OVERRIDE override -#endif - - -#endif // FAKE_CPP11_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/flow_control.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/flow_control.cpp b/examples/cpp/flow_control.cpp deleted file mode 100644 index c0b8739..0000000 --- a/examples/cpp/flow_control.cpp +++ /dev/null @@ -1,249 +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.hpp> -#include <proton/connection_options.hpp> -#include <proton/container.hpp> -#include <proton/default_container.hpp> -#include <proton/delivery.hpp> -#include <proton/listener.hpp> -#include <proton/message.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/receiver_options.hpp> -#include <proton/sender.hpp> -#include <proton/thread_safe.hpp> -#include <proton/tracker.hpp> - -#include <iostream> -#include <sstream> - -#include "fake_cpp11.hpp" - -namespace { - -bool verbose = true; - -void verify(bool success, const std::string &msg) { - if (!success) - throw std::runtime_error("example failure:" + msg); - else { - std::cout << "success: " << msg << std::endl; - if (verbose) std::cout << std::endl; - } -} - -} - -// flow_sender manages the incoming connection and acts as the message sender. -class flow_sender : public proton::messaging_handler { - private: - int available; // Number of messages the sender may send assuming sufficient credit. - int sequence; - - public: - flow_sender() : available(0), sequence(0) {} - - void send_available_messages(proton::sender &s) { - for (int i = sequence; available && s.credit() > 0; i++) { - std::ostringstream mbody; - mbody << "flow_sender message " << sequence++; - proton::message m(mbody.str()); - s.send(m); - available--; - } - } - - void on_sendable(proton::sender &s) OVERRIDE { - if (verbose) - std::cout << "flow_sender in \"on_sendable\" with credit " << s.credit() - << " and " << available << " available messages" << std::endl; - send_available_messages(s); - } - - void on_sender_drain_start(proton::sender &s) OVERRIDE { - if (verbose) - std::cout << "flow_sender in \"on_drain_start\" with credit " << s.credit() - << " and " << available << " available messages" << std::endl; - send_available_messages(s); - if (s.credit()) { - s.return_credit(); // return the rest - } - } - - void set_available(int n) { available = n; } -}; - -class flow_receiver : public proton::messaging_handler { - public: - int stage; - int received; - flow_sender &sender; - - flow_receiver(flow_sender &s) : stage(0), received(0), sender(s) {} - - void example_setup(int n) { - received = 0; - sender.set_available(n); - } - - void run_stage(proton::receiver &r, const std::string &caller) { - // Serialize the progression of the flow control examples. - switch (stage) { - case 0: - if (verbose) std::cout << "Example 1. Simple use of credit." << std::endl; - // TODO: add timeout callbacks, show no messages until credit. - example_setup(2); - r.add_credit(2); - break; - case 1: - if (r.credit() > 0) return; - verify(received == 2, "Example 1: simple credit"); - - if (verbose) std::cout << "Example 2. Use basic drain, sender has 3 \"immediate\" messages." << std::endl; - example_setup(3); - r.add_credit(5); // ask for up to 5 - r.drain(); // but only use what's available - break; - case 2: - if (caller == "on_message") return; - if (caller == "on_receiver_drain_finish") { - // Note that unused credit of 2 at sender is returned and is now 0. - verify(received == 3 && r.credit() == 0, "Example 2: basic drain"); - - if (verbose) std::cout << "Example 3. Drain use with no credit." << std::endl; - example_setup(0); - r.drain(); - break; - } - verify(false, "example 2 run_stage"); - return; - - case 3: - verify(caller == "on_receiver_drain_finish" && received == 0, "Example 3: drain without credit"); - - if (verbose) std::cout << "Example 4. Show using high(10)/low(3) watermark for 25 messages." << std::endl; - example_setup(25); - r.add_credit(10); - break; - - case 4: - if (received < 25) { - // Top up credit as needed. - uint32_t credit = r.credit(); - if (credit <= 3) { - uint32_t new_credit = 10; - uint32_t remaining = 25 - received; - if (new_credit > remaining) - new_credit = remaining; - if (new_credit > credit) { - r.add_credit(new_credit - credit); - if (verbose) - std::cout << "flow_receiver adding credit for " << new_credit - credit - << " messages" << std::endl; - } - } - return; - } - - verify(received == 25 && r.credit() == 0, "Exmaple 4: high/low watermark"); - r.connection().close(); - break; - - default: - throw std::runtime_error("run_stage sequencing error"); - } - stage++; - } - - void on_receiver_open(proton::receiver &r) OVERRIDE { - run_stage(r, "on_receiver_open"); - } - - void on_message(proton::delivery &d, proton::message &m) OVERRIDE { - if (verbose) - std::cout << "flow_receiver in \"on_message\" with " << m.body() << std::endl; - proton::receiver r(d.receiver()); - received++; - run_stage(r, "on_message"); - } - - void on_receiver_drain_finish(proton::receiver &r) OVERRIDE { - if (verbose) - std::cout << "flow_receiver in \"on_receiver_drain_finish\"" << std::endl; - run_stage(r, "on_receiver_drain_finish"); - } -}; - - -class flow_control : public proton::messaging_handler { - private: - std::string url; - proton::listener listener; - flow_sender send_handler; - flow_receiver receive_handler; - - public: - flow_control(const std::string& u) : url(u), receive_handler(send_handler) {} - - void on_container_start(proton::container &c) OVERRIDE { - listener = c.listen(url, proton::connection_options().handler(send_handler)); - c.connect(url); - } - - void on_connection_open(proton::connection &c) OVERRIDE { - if (c.active()) { - // outbound connection - c.open_receiver("flow_example", proton::receiver_options().handler(receive_handler).credit_window(0)); - } - } - - void on_connection_close(proton::connection &) OVERRIDE { - listener.stop(); - } -}; - -int main(int argc, char **argv) { - // Pick an "unusual" port since we are going to be talking to - // ourselves, not a broker. - std::string address("127.0.0.1:8888"); - bool quiet = false; - - example::options opts(argc, argv); - opts.add_value(address, 'a', "address", "connect and send to URL", "URL"); - opts.add_flag(quiet, 'q', "quiet", "suppress additional commentary of credit allocation and consumption"); - - try { - opts.parse(); - if (quiet) - verbose = false; - - flow_control fc(address); - proton::default_container(fc).run(); - - return 0; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - - return 1; -} http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/2f85988e/examples/cpp/helloworld.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp deleted file mode 100644 index 4aa5cdd..0000000 --- a/examples/cpp/helloworld.cpp +++ /dev/null @@ -1,77 +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/container.hpp> -#include <proton/default_container.hpp> -#include <proton/delivery.hpp> -#include <proton/message.hpp> -#include <proton/messaging_handler.hpp> -#include <proton/thread_safe.hpp> -#include <proton/tracker.hpp> -#include <proton/url.hpp> - -#include <iostream> - -#include "fake_cpp11.hpp" - -class hello_world : public proton::messaging_handler { - private: - proton::url url; - - public: - hello_world(const std::string& u) : url(u) {} - - void on_container_start(proton::container& c) OVERRIDE { - c.connect(url); - } - - void on_connection_open(proton::connection& c) OVERRIDE { - c.open_receiver(url.path()); - c.open_sender(url.path()); - } - - void on_sendable(proton::sender &s) OVERRIDE { - proton::message m("Hello World!"); - s.send(m); - s.close(); - } - - void on_message(proton::delivery &d, proton::message &m) OVERRIDE { - std::cout << m.body() << std::endl; - d.connection().close(); - } -}; - -int main(int argc, char **argv) { - try { - std::string url = argc > 1 ? argv[1] : "127.0.0.1:5672/examples"; - - hello_world hw(url); - proton::default_container(hw).run(); - - return 0; - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - - return 1; -} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
