Example #1
0
void
SessionHelperI::connected(const Glacier2::RouterPrx& router, const Glacier2::SessionPrx& session)
{
    //
    // Remote invocation should be done without acquire a mutex lock.
    //
    assert(router);
    Ice::ConnectionPtr conn = router->ice_getCachedConnection();
    string category = router->getCategoryForClient();
    Ice::Long timeout = router->getSessionTimeout();
    
    {
        IceUtil::Mutex::Lock sync(_mutex);
        _router = router;

        if(_destroy)
        {
            //
            // Run the destroyInternal in a thread. This is because it
            // destroyInternal makes remote invocations.
            //
            IceUtil::ThreadPtr thread = new DestroyInternal(this, _callback);
            thread->start().detach();
            return;
        }

        //
        // Cache the category.
        //
        _category = category;

        //
        // Assign the session after _destroy is checked.
        //
        _session = session;
        _connected = true;

        assert(!_refreshThread);
        
        if(timeout > 0)
        {
            _refreshThread = new SessionRefreshThread(this, _router, (timeout)/2);
            _refreshThread->start();
        }
    }
    dispatchCallback(new Connected(_callback, this), conn);
}
Example #2
0
int
CallbackClient::run(int argc, char* argv[])
{
    ObjectPrx routerBase;

    {
        cout << "testing stringToProxy for router... " << flush;
        routerBase = communicator()->stringToProxy("Glacier2/router:default -p 12347 -t 10000");
        cout << "ok" << endl;
    }
    
    Glacier2::RouterPrx router;

    {
        cout << "testing checked cast for router... " << flush;
        router = Glacier2::RouterPrx::checkedCast(routerBase);
        test(router);
        cout << "ok" << endl;
    }

    {
        cout << "installing router with communicator... " << flush;
        communicator()->setDefaultRouter(router);
        cout << "ok" << endl;
    }

    {
        cout << "getting the session timeout... " << flush;
        Ice::Long timeout = router->getSessionTimeout();
        test(timeout == 30);
        cout << "ok" << endl;
    }

    ObjectPrx base;

    {
        cout << "testing stringToProxy for server object... " << flush;
        base = communicator()->stringToProxy("c1/callback:tcp -p 12010 -t 10000");
        cout << "ok" << endl;
    }
        
    {
        cout << "trying to ping server before session creation... " << flush;
        try
        {
            base->ice_ping();
            test(false);
        }
        catch(const ConnectionLostException&)
        {
            cout << "ok" << endl;
        }
    }

    Glacier2::SessionPrx session;

    {
        cout << "trying to create session with wrong password... " << flush;
        try
        {
            session = router->createSession("userid", "xxx");
            test(false);
        }
        catch(const Glacier2::PermissionDeniedException&)
        {
            cout << "ok" << endl;
        }
    }

    {
        cout << "trying to destroy non-existing session... " << flush;
        try
        {
            router->destroySession();
            test(false);
        }
        catch(const Glacier2::SessionNotExistException&)
        {
            cout << "ok" << endl;
        }
    }

    {
        cout << "creating session with correct password... " << flush;
        session = router->createSession("userid", "abc123");
        cout << "ok" << endl;
    }

    {
        cout << "trying to create a second session... " << flush;
        try
        {
            router->createSession("userid", "abc123");
            test(false);
        }
        catch(const Glacier2::CannotCreateSessionException&)
        {
            cout << "ok" << endl;
        }
    }

    {
        cout << "pinging server after session creation... " << flush;
        base->ice_ping();
        cout << "ok" << endl;
    }

    CallbackPrx twoway;

    {
        cout << "testing checked cast for server object... " << flush;
        twoway = CallbackPrx::checkedCast(base);
        test(twoway);
        cout << "ok" << endl;
    }

    ObjectAdapterPtr adapter;

    {
        cout << "creating and activating callback receiver adapter with router... " << flush;
        communicator()->getProperties()->setProperty("Ice.PrintAdapterReady", "0");
        adapter = communicator()->createObjectAdapterWithRouter("CallbackReceiverAdapter", router);
        adapter->activate();
        cout << "ok" << endl;
    }

    string category;

    {
        cout << "getting category from router... " << flush;
        category = router->getCategoryForClient();
        cout << "ok" << endl;
    }

    CallbackReceiverI* callbackReceiverImpl;
    ObjectPtr callbackReceiver;
    CallbackReceiverPrx twowayR;
    CallbackReceiverPrx fakeTwowayR;
    
    {
        cout << "creating and adding callback receiver object... " << flush;
        callbackReceiverImpl = new CallbackReceiverI;
        callbackReceiver = callbackReceiverImpl;
        Identity callbackReceiverIdent;
        callbackReceiverIdent.name = "callbackReceiver";
        callbackReceiverIdent.category = category;
        twowayR = CallbackReceiverPrx::uncheckedCast(adapter->add(callbackReceiver, callbackReceiverIdent));
        Identity fakeCallbackReceiverIdent;
        fakeCallbackReceiverIdent.name = "callbackReceiver";
        fakeCallbackReceiverIdent.category = "dummy";
        fakeTwowayR = CallbackReceiverPrx::uncheckedCast(adapter->add(callbackReceiver, fakeCallbackReceiverIdent));
        cout << "ok" << endl;
    }
    
    {
        cout << "testing oneway callback... " << flush;
        CallbackPrx oneway = CallbackPrx::uncheckedCast(twoway->ice_oneway());
        CallbackReceiverPrx onewayR = CallbackReceiverPrx::uncheckedCast(twowayR->ice_oneway());
        Context context;
        context["_fwd"] = "o";
        oneway->initiateCallback(onewayR, context);
        test(callbackReceiverImpl->callbackOK());
        cout << "ok" << endl;
    }

    {
        cout << "testing twoway callback... " << flush;
        Context context;
        context["_fwd"] = "t";
        twoway->initiateCallback(twowayR, context);
        test(callbackReceiverImpl->callbackOK());
        cout << "ok" << endl;
    }

    //
    // Send 3 twoway request to callback the receiver. The callback
    // receiver only reply to the callback once it received the 3
    // callbacks. This test ensures that Glacier2 doesn't serialize
    // twoway requests (see bug 337 for more information).
    //
    {
        cout << "testing concurrent twoway callback... " << flush;
        Context context;
        context["_fwd"] = "t";
        AMI_Callback_initiateConcurrentCallbackIPtr cb0 = new AMI_Callback_initiateConcurrentCallbackI();
        twoway->initiateConcurrentCallback_async(cb0, 0, twowayR, context);
        AMI_Callback_initiateConcurrentCallbackIPtr cb1 = new AMI_Callback_initiateConcurrentCallbackI();
        twoway->initiateConcurrentCallback_async(cb1, 1, twowayR, context);
        AMI_Callback_initiateConcurrentCallbackIPtr cb2 = new AMI_Callback_initiateConcurrentCallbackI();
        twoway->initiateConcurrentCallback_async(cb2, 2, twowayR, context);
        test(callbackReceiverImpl->answerConcurrentCallbacks(3));
        test(cb0->waitResponse() == 0);
        test(cb1->waitResponse() == 1);
        test(cb2->waitResponse() == 2);
        cout << "ok" << endl;
    }

    {
        cout << "ditto, but with user exception... " << flush;
        Context context;
        context["_fwd"] = "t";
        try
        {
            twoway->initiateCallbackEx(twowayR, context);
            test(false);
        }
        catch(const CallbackException& ex)
        {
            test(ex.someValue == 3.14);
            test(ex.someString == "3.14");
        }
        test(callbackReceiverImpl->callbackOK());
        cout << "ok" << endl;
    }

    {
        cout << "trying twoway callback with fake category... " << flush;
        Context context;
        context["_fwd"] = "t";
        try
        {
            twoway->initiateCallback(fakeTwowayR, context);
            test(false);
        }
        catch(const ObjectNotExistException&)
        {
            cout << "ok" << endl;
        }
    }

    {
        cout << "testing whether other allowed category is accepted... " << flush;
        Context context;
        context["_fwd"] = "t";
        CallbackPrx otherCategoryTwoway = CallbackPrx::uncheckedCast(
            twoway->ice_identity(communicator()->stringToIdentity("c2/callback")));
        otherCategoryTwoway->initiateCallback(twowayR, context);
        test(callbackReceiverImpl->callbackOK());
        cout << "ok" << endl;
    }

    {
        cout << "testing whether disallowed category gets rejected... " << flush;
        Context context;
        context["_fwd"] = "t";
        try
        {
            CallbackPrx otherCategoryTwoway = CallbackPrx::uncheckedCast(
                twoway->ice_identity(communicator()->stringToIdentity("c3/callback")));
            otherCategoryTwoway->initiateCallback(twowayR, context);
            test(false);
        }
        catch(const ObjectNotExistException&)
        {
            cout << "ok" << endl;
        }
    }

    {
        cout << "testing whether user-id as category is accepted... " << flush;
        Context context;
        context["_fwd"] = "t";
        CallbackPrx otherCategoryTwoway = CallbackPrx::uncheckedCast(
            twoway->ice_identity(communicator()->stringToIdentity("_userid/callback")));
        otherCategoryTwoway->initiateCallback(twowayR, context);
        test(callbackReceiverImpl->callbackOK());
        cout << "ok" << endl;
    }

    {
        cout << "testing buffered mode... " << flush;

        //
        // Start 3 misbehaving clients.
        //
        const int nClients = 3; // Passwords need to be added to the password file if more clients are needed.
        int i;
        vector<MisbehavedClientPtr> clients;
        for(i = 0; i < nClients; ++i)
        {
            clients.push_back(new MisbehavedClient(i));
            clients.back()->start();
            clients.back()->waitForCallback();
        }

        //
        // Sleep for one second to make sure the router starts sending
        // the callback with the payload to the clients.
        //
        IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1));

        //
        // Initiate few callbacks with a large payload. Because of 
        // the buffered mode, this shouldn't block even though the
        // misbehaved client are not answering their callback
        // requests.
        //
        Context context;
        context["_fwd"] = "t";
        twoway->initiateCallbackWithPayload(twowayR, context);
        test(callbackReceiverImpl->callbackWithPayloadOK());
        twoway->initiateCallbackWithPayload(twowayR, context);
        test(callbackReceiverImpl->callbackWithPayloadOK());
        twoway->initiateCallbackWithPayload(twowayR, context);
        test(callbackReceiverImpl->callbackWithPayloadOK());
        twoway->initiateCallbackWithPayload(twowayR, context);
        test(callbackReceiverImpl->callbackWithPayloadOK());

        for(vector<MisbehavedClientPtr>::const_iterator p = clients.begin(); p != clients.end(); ++p)
        {
            (*p)->notifyWaitCallback();
            (*p)->getThreadControl().join();
        }

        cout << "ok" << endl;
    }

    {
        cout << "stress test... " << flush;
        const int nClients = 3; // Passwords need to be added to the password file if more clients are needed.
        int i;
        vector<StressClientPtr> clients;
        for(i = 0; i < nClients; ++i)
        {
            switch(IceUtil::random(3))
            {
            case 0:
                clients.push_back(new PingStressClient(i));
                break;
            case 1:
                clients.push_back(new CallbackStressClient(i));
                break;
            case 2:
                clients.push_back(new CallbackWithPayloadStressClient(i));
                break;
            default:
                assert(false);
                break;
            }
            clients.back()->start();
        }
        for(vector<StressClientPtr>::const_iterator p = clients.begin(); p != clients.end(); ++p)
        {
            (*p)->notifyThread();
        }

        //
        // Let the stress client run for a bit.
        //
        IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(3));

        //
        // Send some callbacks.
        //
        Context context;
        context["_fwd"] = "t";
        twoway->initiateCallback(twowayR);
        test(callbackReceiverImpl->callbackOK());

        //
        // Kill the stress clients.
        //
        for(vector<StressClientPtr>::const_iterator q = clients.begin(); q != clients.end(); ++q)
        {
            (*q)->kill();
            (*q)->getThreadControl().join();
        }


        cout << "ok" << endl;
    }

    {
        cout << "testing server shutdown... " << flush;
        twoway->shutdown();
        // No ping, otherwise the router prints a warning message if it's
        // started with --Ice.Warn.Connections.
        cout << "ok" << endl;
        /*
          try
          {
          base->ice_ping();
          test(false);
          }
          // If we use the glacier router, the exact exception reason gets
          // lost.
          catch(const UnknownLocalException&)
          {
          cout << "ok" << endl;
          }
        */
    }
    
    {
        cout << "destroying session... " << flush;
        try
        {
            router->destroySession();
            test(false);
        }
        catch(const Ice::ConnectionLostException&)
        {
        }
        catch(const Ice::LocalException&)
        {
            test(false);
        }
        cout << "ok" << endl;
    }

    {
        cout << "trying to ping server after session destruction... " << flush;
        try
        {
            base->ice_ping();
            test(false);
        }
        catch(const ConnectionLostException&)
        {
            cout << "ok" << endl;
        }
    }

    if(argc >= 2 && strcmp(argv[1], "--shutdown") == 0)
    {
        {
            cout << "uninstalling router with communicator... " << flush;
            communicator()->setDefaultRouter(0);
            cout << "ok" << endl;
        }

        ObjectPrx adminBase;

        {
            cout << "testing stringToProxy for admin object... " << flush;
            adminBase = communicator()->stringToProxy("Glacier2/admin:tcp -h 127.0.0.1 -p 12348 -t 10000");
            cout << "ok" << endl;
        }
        
/*
        {
            cout << "uninstalling router with admin object... " << flush;
            adminBase->ice_router(0);
            cout << "ok" << endl;
        }
*/

        Glacier2::AdminPrx admin;
        
        {
            cout << "testing checked cast for admin object... " << flush;
            admin = Glacier2::AdminPrx::checkedCast(adminBase);
            test(admin);
            cout << "ok" << endl;
        }

        cout << "testing Glacier2 shutdown... " << flush;
        admin->shutdown();
        try
        {
            admin->ice_ping();
            test(false);
        }
        catch(const Ice::LocalException&)
        {
            cout << "ok" << endl;
        }
    }
    
    return EXIT_SUCCESS;
}
Example #3
0
void
SessionHelperI::connected(const Glacier2::RouterPrx& router, const Glacier2::SessionPrx& session)
{
    //
    // Remote invocation should be done without acquiring a mutex lock.
    //
    assert(router);
    Ice::ConnectionPtr conn = router->ice_getCachedConnection();
    string category = router->getCategoryForClient();
    Ice::Int acmTimeout = 0;
    try
    {
        acmTimeout = router->getACMTimeout();
    }
    catch(const Ice::OperationNotExistException&)
    {
    }

    if(acmTimeout <= 0)
    {
        acmTimeout = static_cast<Ice::Int>(router->getSessionTimeout());
    }

    //
    // We create the callback object adapter here because createObjectAdapter internally
    // makes synchronous RPCs to the router. We can't create the OA on-demand when the
    // client calls objectAdapter() or addWithUUID() because they can be called from the
    // GUI thread.
    //
    if(_useCallbacks)
    {
        _adapter = _communicator->createObjectAdapterWithRouter("", router);
        _adapter->activate();
    }

    bool destroy;
    {
        IceUtil::Mutex::Lock sync(_mutex);
        _router = router;
        destroy = _destroy;

        if(!_destroy)
        {
            //
            // Cache the category.
            //
            _category = category;

            //
            // Assign the session after _destroy is checked.
            //
            _session = session;
            _connected = true;

            if(acmTimeout > 0)
            {
                Ice::ConnectionPtr connection = _router->ice_getCachedConnection();
                assert(connection);
                connection->setACM(acmTimeout, IceUtil::None, Ice::HeartbeatAlways);
                connection->setCallback(new ConnectionCallbackI(this));
            }
        }
    }

    if(destroy)
    {
        //
        // connected() is only called from the ConnectThread so it is ok to
        // call destroyInternal here.
        //
        destroyInternal(new Disconnected(this, _callback));
    }
    else
    {
        dispatchCallback(new Connected(_callback, this), conn);
    }
}