summaryrefslogtreecommitdiff
path: root/trunk/TAO/orbsvcs/tests/Bug_2285_Regression/ServerRequest_Interceptor2.cpp
blob: 3736fc94f3ed6677ced237e93e285ca0451ad765 (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
// -*- C++ -*-

#include "ServerRequest_Interceptor2.h"
#include "orbsvcs/FT_CORBA_ORBC.h"
#include "tao/IOP_IORC.h"
#include "tao/ORB_Constants.h"
#include "tao/AnyTypeCode/DynamicC.h"
#include "tao/AnyTypeCode/TypeCode.h"
#include "tao/CDR.h"
#include "ace/Log_Msg.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_unistd.h"
#include "Hello.h"
#include "ace/OS_NS_sys_time.h"

ACE_RCSID (FaultTolerance,
           TAO249_ServerRequest_Interceptor2,
           "$Id$")

TAO249_ServerRequest_Interceptor2::TAO249_ServerRequest_Interceptor2 (void)
: orb_ (0),
  client_id_ (0)
{
}

TAO249_ServerRequest_Interceptor2::~TAO249_ServerRequest_Interceptor2 (void)
{
}


char *
TAO249_ServerRequest_Interceptor2::name (void)
{
  return CORBA::string_dup ("TAO_TAO249_ServerRequest_Interceptor2");
}

void
TAO249_ServerRequest_Interceptor2::destroy (void)
{
}

void
TAO249_ServerRequest_Interceptor2::receive_request_service_contexts (
  PortableInterceptor::ServerRequestInfo_ptr)
{
}

void
TAO249_ServerRequest_Interceptor2::receive_request (
  PortableInterceptor::ServerRequestInfo_ptr ri)
{
  CORBA::String_var op = ri->operation ();

  if (ACE_OS::strcmp (op.in (), "drop_down_dead"))
  {
    // bail if not the op we are interested in -
    // avoid excess spurious error clutter when client calls ::shutdown
    return;
  }

  try
  {
    IOP::ServiceContext_var sc =
      ri->get_request_service_context (IOP::FT_REQUEST);

    TAO_InputCDR cdr (reinterpret_cast <const char*>
                                       (sc->context_data.get_buffer ()
                                        ),
                                       sc->context_data.length ());

    CORBA::Boolean byte_order;

    if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
      {
        throw CORBA::BAD_PARAM (CORBA::OMGVMCID | 28, CORBA::COMPLETED_NO);
      }

    cdr.reset_byte_order (static_cast <int>(byte_order));

    FT::FTRequestServiceContext ftrsc;

    if ((cdr >> ftrsc) == 0)
      throw CORBA::BAD_PARAM (CORBA::OMGVMCID | 28, CORBA::COMPLETED_NO);

    FILE* last_exp_time_file = ACE_OS::fopen ("last_expiration_time", "r+");
    TimeBase::TimeT last_exp_time = 0;

    if (!last_exp_time_file)
      {
        // file does not exist ... we're the first server
        // create new file for the expiration time
        last_exp_time_file = ACE_OS::fopen ("last_expiration_time", "w+");
        last_exp_time = ftrsc.expiration_time;
      }
    else
      {
        // We're a subsequent server... read in the previous server's expiration time
        ACE_OS::fread (&last_exp_time,
                       1,
                       sizeof (TimeBase::TimeT),
                       last_exp_time_file);
        ACE_OS::sleep (1);
      }

    if (last_exp_time != ftrsc.expiration_time)
      {
        ACE_DEBUG ((LM_DEBUG, "Test Failed - REGRESSION !!! Different expiration times used on consecutive retries of the same op!!\n"));
        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Previous expiration: %Q\n"), last_exp_time));
        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Current expiration : %Q\n"), ftrsc.expiration_time));
        return;
      }


    // This is the offset from UTC to posix - a value less than than this will
    // indicate posix is (mistakenly) being used
    TimeBase::TimeT the_seventies = ACE_UINT64_LITERAL (0x1B21DD213814000);

    // @warning - this test is fragile. It will break in 2358 A.D. :-)
    if (last_exp_time <= the_seventies)
      {
        ACE_DEBUG ((LM_ERROR, "Test Failed - REGRESSION !!! Expiration time is in wrong format - it is before 1970 A.D. !!\n"));
        ACE_DEBUG ((LM_DEBUG, "Expiration time: %Q\n", last_exp_time));
        ACE_DEBUG ((LM_DEBUG, "1970 A.D.      : %Q\n", the_seventies));
        return;
      }
    else if ( last_exp_time > (the_seventies * 2))
      {
        ACE_DEBUG ((LM_ERROR, "Test Failed - REGRESSION !!! Expiration time is garbage - it is after 2358 A.D. !!\n"));
        ACE_DEBUG ((LM_DEBUG, "Expiration time: %Q\n", last_exp_time));
        ACE_DEBUG ((LM_DEBUG, "2358 A.D.      : %Q\n", (the_seventies * 2)));
        return;
      }

    TimeBase::TimeT now = get_now ();

    if (now > last_exp_time)
      {
        // We have passed the exp time... there should be no more retries received after this point...
        FILE* no_more_retries = ACE_OS::fopen ("no_more_retries", "r+");
        if (no_more_retries)
          {
            TimeBase::TimeT last_expired_attempt = 0;
            ACE_OS::fread (&last_expired_attempt, 1, sizeof (TimeBase::TimeT), no_more_retries);
            ACE_OS::fclose (no_more_retries);

            // There has already been an attempt after the last server passed the expiration time
            ACE_DEBUG ((LM_ERROR, "Test Failed - REGRESSION !!! Client ORB is still retrying after the expiration time!!\n"));
            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Expiration time  : %Q\n"), last_exp_time));
            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Previous attempt : %Q\n"), last_expired_attempt));
            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Time now         : %Q\n"), now));
            return;
          }
        else
          {
            // Tell the next server we've passed the point of no return
            no_more_retries = ACE_OS::fopen ("no_more_retries", "w+");
            ACE_OS::fwrite (&now, 1, sizeof (TimeBase::TimeT), no_more_retries);
            ACE_OS::fflush (no_more_retries);
            ACE_OS::fclose (no_more_retries);
          }
      }

    // Everthing is fine so far. Write out the expiration time for the next server to check
    ACE_OS::fwrite (&ftrsc.expiration_time, 1, sizeof (TimeBase::TimeT), last_exp_time_file);
    ACE_OS::fflush (last_exp_time_file);
    ACE_OS::fclose (last_exp_time_file);

    // Goodbye cruel world !!
    ACE_OS::abort ();
  }
catch (const CORBA::Exception& ex)
  {
    ACE_DEBUG ((LM_ERROR, "Unexpected (non regression problem) error - test failed\n"));
    ex._tao_print_exception (
      "Exception in TAO249_ServerRequest_Interceptor2::receive_request \n");
    throw;
  }

}

TimeBase::TimeT
TAO249_ServerRequest_Interceptor2::get_now (void)
{
  // 1582...
  const TimeBase::TimeT timeOffset = ACE_UINT64_LITERAL (0x1B21DD213814000);

  // Now in posix
  ACE_Time_Value time_value = ACE_OS::gettimeofday ();

  TimeBase::TimeT sec_part  = time_value.sec ();
  sec_part = sec_part  * 10000000;
  TimeBase::TimeT usec_part = time_value.usec ();
  usec_part = usec_part * 10;
  return (sec_part + usec_part + timeOffset);
}

void
TAO249_ServerRequest_Interceptor2::send_reply (
  PortableInterceptor::ServerRequestInfo_ptr)
{
}

void
TAO249_ServerRequest_Interceptor2::send_exception (
  PortableInterceptor::ServerRequestInfo_ptr)
{
}

void
TAO249_ServerRequest_Interceptor2::send_other (
  PortableInterceptor::ServerRequestInfo_ptr)
{
}