summaryrefslogtreecommitdiff
path: root/TAO/docs/tutorials/Quoter/RTCORBA/Broker.cpp
blob: e3aa2a1a29350b4aac898cca391938520edf2f6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// $Id$

// ACE header files
#include "ace/Get_Opt.h"
#include "ace/OS_NS_stdlib.h"
#include "orbsvcs/CosNamingC.h"

// STL strings
#include <iostream>
#include <string>

// local header files
#include "Broker_i.h"
#include "Distributor_i.h"
#include "Stock_PriorityMapping.h"

using Stock::Priority_Mapping;

// Name of the file that stores the StockDistributor IOR.
static std::string ior = "file://StockDistributor.ior";

// Name of the StockDistributor registered with the Naming Service.
static std::string distributor_name = "StockDistributor";

// Default priority level for running the broker.
static Priority_Mapping::Priority priority_level
    = Priority_Mapping::MEDIUM;

// Default stock name.
static std::string stock_name = "IBM";

// A flag that indicates use of the Naming Service.
bool use_naming = false;

static int
parse_args (int argc, ACE_TCHAR *argv[])
{
  ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:p:n:c"));
  int c;

  while ((c = get_opts ()) != -1)
    {
      switch (c)
        {
        case 'o':
          ior = get_opts.opt_arg ();
          break;
        case 'p':
          switch (ACE_OS::atoi (get_opts.opt_arg ()))
            {
            case 0:
              priority_level = Priority_Mapping::VERY_LOW;
              break;

            case 1:
              priority_level = Priority_Mapping::LOW;
              break;

            case 2:
              priority_level = Priority_Mapping::MEDIUM;
              break;

            case 3:
              priority_level = Priority_Mapping::HIGH;
              break;

            case 4:
              priority_level = Priority_Mapping::VERY_HIGH;
              break;

            default:
              std::cerr << "Warning: Invalid priority detected, defaulting to very low.\n";
              priority_level = Priority_Mapping::VERY_LOW;
              break;

            }
          break;

        case 'n':
          stock_name = get_opts.opt_arg ();
          break;
        case 'c':
          use_naming = true;
          break;

        case '?':
        default:
          ACE_ERROR_RETURN ((LM_ERROR,
                             "usage: %s\n"
                             "-o <Distributor IOR> (default is file://StockDistributor.ior)\n"
                             "-p <Priority> (default is 2)\n"
                             "-n <Stock name> (default is IBM)\n"
                             "-c Use the naming service"
                             "\n",
                             argv [0]),
                            -1);
        }
    }

  return 0;
}

static CORBA::Object_ptr
get_distributor_reference (CORBA::ORB_ptr orb)
{
  if (use_naming)
    {
      CORBA::Object_var tmp =
        orb->resolve_initial_references ("NameService");

      CosNaming::NamingContext_var pns =
        CosNaming::NamingContext::_narrow (tmp.in ());

      CosNaming::Name name (1);
      name.length (1);
      name[0].id = distributor_name.c_str ();

      return pns->resolve (name);
    }
  else
    // Read and destringify the Stock_Distributor object's IOR.
    return orb->string_to_object (ior.c_str ());
}

int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
  try
    {
      // Initialiaze the ORB.
      CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);

      // This call MUST come after ORB_init(), which may need to
      // extract -ORB options first.
      if (parse_args (argc, argv) != 0)
        return 1;

      // Get a reference to the RootPOA.
      CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA");
      PortableServer::POA_var poa = PortableServer::POA::_narrow (obj.in ());

      // Activate the POAManager.
      PortableServer::POAManager_var mgr = poa->the_POAManager ();
      mgr->activate ();

      // Read and destringify the Stock_Distributor object's IOR.
      obj = get_distributor_reference (orb.in ());

      // Narrow the IOR to a Stock_Distributor object reference.
      Stock::StockDistributor_var stock_distributor =
        Stock::StockDistributor::_narrow (obj.in ());

      if (CORBA::is_nil (stock_distributor.in ()))
        ACE_ERROR_RETURN ((LM_DEBUG,
                           "Nil StockDistributor object reference <%s>\n",
                           ior.c_str ()),
                          1);

      // Create an instance of the <StockBroker>.

      // Create the factory object. Create a <Stock::StockBroker>.
      Stock_StockBrokerHome_i stock_broker_home (orb.in ());
      Stock::StockBroker_var stock_broker =
        stock_broker_home.create (stock_distributor.in (),
                                  stock_name.c_str ());

      if (CORBA::is_nil (stock_broker.in ()))
        ACE_ERROR_RETURN ((LM_DEBUG,
                           "Nil StockBroker object reference <%s>\n",
                           ior.c_str ()),
                          1);

      // Create a new consumer and initialize it.
      Stock::StockNameConsumer_var consumer =
        stock_broker->get_consumer_notifier ();

      // Subscribe the consumer with the distributor.
      ::Stock::Cookie_var cookie =
        stock_distributor->subscribe_notifier (consumer.in (), priority_level);

      consumer->cookie_ (cookie.in ());

      // Get the object reference to a StockQuoter that's been
      // activated at the appropriate priority.
      Stock::StockQuoter_var stock_quoter =
        stock_distributor->provide_quoter_info (cookie.in ());

      if (CORBA::is_nil (stock_quoter.in ()))
        ACE_ERROR_RETURN ((LM_ERROR,
                           "ERROR: Quoter reference was nil!\n"),
                          -1);

      // Stash the stock_quoter object reference away for later use.
      stock_broker->connect_quoter_info (stock_quoter.in ());

      // Run the event loop.
      ACE_DEBUG ((LM_DEBUG,
                  "running the event loop:\n"
                  "*** message: ready to receieve stock information...\n\n"));
      orb->run ();

      // Cleanup the POA and ORB.
      poa->destroy (1, 1);
      orb->destroy ();
    }
  catch (CORBA::Exception &ex)
    {
      ex._tao_print_exception ("Exception caught:");
      return 1;
    }
  catch (...)
    {
      ACE_ERROR ((LM_ERROR, "Broker: Caught unknown C++ exception\n"));
    }

  return 0;
}