[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference pamsrc::objectbroker_development

Title:ObjectBroker Development - BEA Systems' CORBA
Notice:See note 2 for kit locations; note 4 for training
Moderator:RECV::GUMBELd
Created:Thu Dec 27 1990
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2482
Total number of notes:13057

2431.0. "OBB_MGT_RIIterator fails after restarting agent..." by MIASYS::DLUGOSZ (My reality check just bounced) Mon Feb 10 1997 17:12

    Ok, I'm missing something. Maybe somebody can see what?
    
    I've a utility program that uses the Management API to manipulate
    the agent and implementations (well the agent part actually just
    spawns the appropriate "net ... objectbroker" command).
    
    If the agent is stopped and I start the utility I can start the
    agent (from the utliity) and get a list of implementations (after
    I start some). 
    
    If I stop the agent from the utility and then start it again it
    fails to get the implementations; specificly the first call to
    OBB_MGT_RIIterator_next_n throws an exception - CORBA_COMM_FAILURE;
    OBB_INV_TRANSERR, "The descriptor is not a socket". The previous
    calls to get_ri_iterator and get_agent succeeded. After stopping 
    the agent I did release the agent object. The was no other "global"
    data that might be holding garbage.
    
    Any ideas?
    Ron
    
T.RTitleUserPersonal
Name
DateLines
2431.1Post sample code - PleaseREQUE::ctxobj.zko.dec.com::PatrickObjectBroker EngineeringTue Feb 11 1997 08:258
Could you post a sample code fragment?

I can't tell if when you start the Agent, you obtain a new Agent objref,
and then obtain a new iterator objref. 



Paul Patrick
2431.2They're both new - will post codeMIASYS::DLUGOSZMy reality check just bouncedTue Feb 11 1997 08:5810
    The code is a C++ class - I'll try to upload it later.
    
    When the agent is stopped I release the old reference. I obtain a new
    reference after it is started. The iterator is a local variable within
    a method. It is released on all exit paths from the method. It doesn't
    have much choice but to be a new reference.
    
    I post the code later this morning.
    
    Ron
2431.3agent.hMIASYS::DLUGOSZMy reality check just bouncedTue Feb 11 1997 15:5070
#ifndef __AGENT_H__
#define __AGENT_H__

#include "orb.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <obbmgt.h>
#ifdef __cplusplus
}
#endif

#include "OBB32Ext.h"

extern CWinApp *g_pMyApp;

class AFX_EXT_CLASS CImplEntry : public CObject
{
    DECLARE_DYNAMIC(CImplEntry);

public:
    CString         m_strImplName;
    CString         m_strImplUUID;
    CString         m_strInstUUID;
    CString         m_strTimeReg;
    CString         m_strState;
    CString         m_strSelectState;
    CORBA_Object    m_objRunningImpl;
 
public:
    CImplEntry();
    virtual ~CImplEntry();

};



class AFX_EXT_CLASS CAgent : public CObject
{
    DECLARE_DYNAMIC(CAgent);

    OBB_MGT_Agent     m_objAgent;
    CEnvironment      m_Env;
    CListCtrl*        m_pListCtrl;
    CObList           m_ImplList;
    char              m_szSelText[256];
 
public:
    CAgent();
    virtual ~CAgent();

    BOOL StartAgent(CStringList& rCmdRespList); 
    BOOL StopAgent(CStringList& rCmdRespList); 
    BOOL GetAgentStatus(CStringList& rCmdRespList);
    BOOL GetAgent(char* pszNodeName);
    void DeleteAgent(void);
    BOOL IsInitialized(void)    { if (m_objAgent == NULL) return FALSE; else return TRUE; }
    void InitializeListCtrl(CListCtrl* pListCtrl);
    void DisplayImpls(void);
    void GetDisplayInfo(NMHDR* pNMHDR);
    void DeleteImplList();
    BOOL GetIterator(OBB_MGT_RIIterator* pIterator);
    OBB_MGT_RIIterator_RIInfo* GetNextImpl(OBB_MGT_RIIterator Iterator, OBB_MGT_RIIterator_ImplInfoSeq* pImplSeq);
    BOOL GetImplAttributes(CORBA_Object pobjRunningImpl, CImplEntry* pEntry);
    BOOL PurgeImpls(void);
    BOOL GetImpls(void);
    BOOL StopImpl(CImplEntry* pImplEntry);
    BOOL SpawnCommand(CString strCommandLine, CStringList& rCmdRespList);
};
#endif
2431.4OBBAGENT.CPPMIASYS::DLUGOSZMy reality check just bouncedTue Feb 11 1997 15:50575
// OBBAgent.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "Agent.h"
#include <afxdllx.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


static AFX_EXTENSION_MODULE OBBAgentDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		TRACE0("OBBAGENT.DLL Initializing!\n");
		
		// Extension DLL one-time initialization
		AfxInitExtensionModule(OBBAgentDLL, hInstance);

		// Insert this DLL into the resource chain
		new CDynLinkLibrary(OBBAgentDLL);
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		TRACE0("OBBAGENT.DLL Terminating!\n");
	}
	return 1;   // ok
}


IMPLEMENT_DYNAMIC(CImplEntry, CObject)

CImplEntry::CImplEntry()
{
}

CImplEntry::~CImplEntry()
{
}

IMPLEMENT_DYNAMIC(CAgent, CObject)

CAgent::CAgent()
{
    m_objAgent     = NULL;
}

CAgent::~CAgent()
{
    DeleteAgent();
}


BOOL CAgent::GetAgent(char* pszNodeName)
{
    OBB_MGT_get_agent(pszNodeName, &m_Env, &m_objAgent);
    if (m_Env.IsException())
    {
        m_Env.ReportSystemException("Exception raised getting agent object");
        m_objAgent = NULL;
        return FALSE;
    }

    m_pListCtrl->EnableWindow();
    return TRUE;
}

void CAgent::DeleteAgent(void)
{
    DeleteImplList();
    if (m_objAgent != NULL)
    {
        CORBA_Object_release(m_objAgent, &m_Env);
        m_objAgent = NULL;
    }

    // Need to clear list control and disable it to
    // let user now ...
}

void CAgent::DeleteImplList()
{
    while (!m_ImplList.IsEmpty())
        delete m_ImplList.RemoveHead();

    ASSERT(m_ImplList.IsEmpty());
}


BOOL CAgent::GetAgentStatus(CStringList& rCmdRespList) 
{
    // This is a quick hack for now - but it does the job
    return (SpawnCommand("obbmsho -A", rCmdRespList));
}

BOOL CAgent::StartAgent(CStringList& rCmdRespList) 
{
    // Start the agent - we "assume" it is started for now
    // If it isn't GetAgent will throw an exception
    if (!SpawnCommand("net start objectbroker", rCmdRespList))
        return FALSE;

    return TRUE;
}

BOOL CAgent::StopAgent(CStringList& rCmdRespList) 
{
    BOOL bStatus = SpawnCommand("net stop objectbroker", rCmdRespList);

    // Need to release the current agent object since it will no
    // longer be valid if a new agent is started.
    CORBA_Object_release(m_objAgent, &m_Env);
    if (m_Env.IsException())
    {
        m_Env.ReportSystemException("Failed to release agent object");
        bStatus = FALSE;
    }

    m_objAgent = NULL;
//    DeleteImplList();
//    m_pListCtrl->EnableWindow(FALSE);

    return bStatus;
}


BOOL CAgent::SpawnCommand(CString strCmdLine, CStringList& rCmdRespList)
{
    const int DATA_BUFFER_SIZE = 80;

    SECURITY_ATTRIBUTES sa = {0};
    STARTUPINFO         si = {0};
    PROCESS_INFORMATION pi = {0};

    HANDLE hPipeWrite1 = NULL, hPipeWrite2 = NULL;
    HANDLE hPipeRead1  = NULL, hPipeRead2  = NULL;

    char szReadBuffer[2];
    CString strDataBuffer;

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    // Create pipe for output redirection
    if (!(CreatePipe(&hPipeRead1, &hPipeWrite1, &sa, 0)))
    {
        TRACE("Failed to create pipe.\n");
        return FALSE;
    }

    // Create pipe for input redirection. Need the handle to set
    // up the hStdInput field of the STARTUPINFO struct
    if (!(CreatePipe(&hPipeRead2, &hPipeWrite2, &sa, 0)))
    {
        TRACE("Failed to create pipe.\n");
        return FALSE;
    }

    // Make sure child uses hPipeWrite1 as stdout. Also don't want
    // it to show on the screen.
    si.cb           = sizeof(si);
    si.dwFlags      = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow  = SW_HIDE;
    si.hStdInput    = hPipeWrite2;
    si.hStdOutput   = hPipeWrite1;
    si.hStdError    = hPipeWrite1;

    if (!(CreateProcess(NULL, strCmdLine.GetBuffer(strCmdLine.GetLength()), 
                        NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)))
    {
        TRACE("Failed to create process.\n");
        return FALSE;
    }

    // Close write handle so we don't use it accidently
    CloseHandle(hPipeWrite1);

    DWORD dwBytesRead = 0;
    BOOL bDataInPipe = TRUE;

    while (bDataInPipe)
    {
        char* pData = strDataBuffer.GetBuffer(DATA_BUFFER_SIZE);
        ZeroMemory(pData, DATA_BUFFER_SIZE);

        while (TRUE)
        {
            ZeroMemory(szReadBuffer, 2);
            if(ReadFile(hPipeRead1, szReadBuffer, 1, &dwBytesRead, NULL))
            {
                if (strncmp(szReadBuffer, "\n", 1) != 0)
                    strncat(pData, szReadBuffer, dwBytesRead);
                else
                    break;
            }

            if (dwBytesRead == 0)
            {
                bDataInPipe = FALSE;
                break;
            }
        }

        strDataBuffer.ReleaseBuffer();
        strDataBuffer.TrimRight();

        if (strDataBuffer.GetLength() > 0)
            rCmdRespList.AddTail(strDataBuffer);
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(hPipeRead1);

    return TRUE;
}

BOOL CAgent::StopImpl(CImplEntry* pImplEntry)
{
    if (m_objAgent == NULL)
        return FALSE;

    BOOL bStatus = TRUE;

    CString strMsg = "Are you sure you want to stop ";
    strMsg += pImplEntry->m_strImplName + "?";
    if (AfxMessageBox (strMsg, MB_YESNO) == IDYES)
    {
        CORBA_Object objImpl;
        objImpl = CORBA_Object_duplicate(pImplEntry->m_objRunningImpl, &m_Env);
        if (m_Env.IsException())
        {
            m_Env.ReportSystemException("Could not duplicate running impl object");
            bStatus = FALSE;
        }

        OBB_MGT_RunningImpl_stop(objImpl, &m_Env, OBB_MGT_FLAG_NOTIFY_IMPL);
        if (m_Env.IsException())
        {
            if (m_Env.GetStatus() == OBB_MGT_NOMORIMPLS)
            {
                bStatus = TRUE;
            }
            else if (m_Env.GetStatus() == OBB_INV_MSINSTNOTFND)
            {
                m_Env.ReportSystemException("Could not not stop running impl");
                bStatus = FALSE;
            }
        }

        if (!bStatus)
            return bStatus;

        return (GetImpls());        
    }

    return TRUE;
}

BOOL CAgent::PurgeImpls(void)
{
    if (m_objAgent == NULL)
        return FALSE;

    OBB_MGT_Agent_purge_impls(m_objAgent, &m_Env, (OBB_MGT_Flags) 0);
    if (m_Env.IsException())
    {
        m_Env.ReportSystemException("Exception raised purging dead impls");
        return FALSE;
    }

    return TRUE;
}


BOOL CAgent::GetIterator(OBB_MGT_RIIterator* pIterator)
{
    if (m_objAgent == NULL)
        return FALSE;

    OBB_MGT_Agent_get_ri_iterator(m_objAgent, &m_Env, pIterator);
    if (m_Env.IsException())
    {
        m_Env.ReportSystemException("Exception raised getting iterator");
        return FALSE;
    }

    return TRUE;
}

OBB_MGT_RIIterator_RIInfo* CAgent::GetNextImpl(OBB_MGT_RIIterator Iterator, 
                                               OBB_MGT_RIIterator_ImplInfoSeq* pImplSeq)
{
    if (m_objAgent == NULL)
        return (OBB_MGT_RIIterator_RIInfo*) NULL;

    OBB_MGT_RIIterator_next_n(Iterator, &m_Env, 1, pImplSeq);
    if (m_Env.IsException())
    {
        if (m_Env.GetStatus() == OBB_MGT_NOMORIMPLS)
        {
            return (OBB_MGT_RIIterator_RIInfo*) NULL;
        }
        
        m_Env.ReportSystemException("Exception raised getting iterator");
        return (OBB_MGT_RIIterator_RIInfo*) NULL;
    }

    return (OBB_MGT_RIIterator_RIInfo*) pImplSeq->_buffer;
}


BOOL CAgent::GetImplAttributes(CORBA_Object objRunningImpl, CImplEntry* pEntry)
{
    if (m_objAgent == NULL)
        return FALSE;

    OBB_MGT_NamedUnionSeq Attributes;
    Attributes._buffer = NULL;

    OBB_MGT_RunningImpl_get_attrs(objRunningImpl, &m_Env, (OBB_MGT_Flags) 0,
                                  (OBB_MGT_NamedUnionSeq*) NULL, &Attributes);
    if (m_Env.IsException())
    {
        if (m_Env.GetStatus() == OBB_INV_MSINSTNOTFND)
        {
            TRACE("Could not get attributes for implementation!\n");
        }
        else
        {
            m_Env.ReportSystemException("Exception raised getting impl attributes");
            return FALSE;
        }

        if (Attributes._buffer != NULL)
            CORBA_free(Attributes._buffer);

        return FALSE;
    }

    // Check to see if the impl is "Executing" (i.e., running)
    OBB_MGT_NamedUnion* pImplAttr = Attributes._buffer;

    // Get what we need out of the attributes structure
    unsigned int unIndex;
    for (unIndex = 0; unIndex < Attributes._length; unIndex++, pImplAttr++)
    {
        if (strcmp(pImplAttr->Name, OBB_MGT_ATTR_State) == 0)
        {    
            switch (pImplAttr->Value._u.ULongVal)
            {
                case OBB_MGT_RunningImpl_STARTING:
                    pEntry->m_strState = "Starting";
                    break;

                case OBB_MGT_RunningImpl_RUNNING:
                    pEntry->m_strState = "Executing";
                    break;

                case OBB_MGT_RunningImpl_TERMINATING:
                    pEntry->m_strState = "Terminating";
                    break;

                case OBB_MGT_RunningImpl_DEAD:
                    pEntry->m_strState = "Dead";
                    break;

                default:
                    pEntry->m_strState = "Unknown";
            }
        }

        if (strcmp(pImplAttr->Name, OBB_MGT_ATTR_TimeRegistered) == 0)
        {   
            pEntry->m_strTimeReg = pImplAttr->Value._u.IdVal;
        }

        if (strcmp(pImplAttr->Name, OBB_MGT_ATTR_SelectState) == 0)
        {   
            switch (pImplAttr->Value._u.ULongVal)
            {
                case OBB_MGT_RunningImpl_ENABLED:
                    pEntry->m_strSelectState = "Enabled";
                    break;

                case OBB_MGT_RunningImpl_DISABLED:
                    pEntry->m_strSelectState = "Disabled";
                    break;

                default:
                    pEntry->m_strSelectState = "Unknown";
            }
        }

    }

    if (Attributes._buffer != NULL)
        CORBA_free(Attributes._buffer);

    return TRUE;
}


BOOL CAgent::GetImpls(void)
{
    if (m_objAgent == NULL)
        return FALSE;

    // Delete the old list of impls and clear the list control
    DeleteImplList();
    m_pListCtrl->DeleteAllItems();

    // The first thing to do is get an RI Iterator
    OBB_MGT_RIIterator Iterator;
    if (!GetIterator(&Iterator))
        return FALSE;

    BOOL bStatus = TRUE;

    // Now loop until we run out of impls
    OBB_MGT_RIIterator_ImplInfoSeq ImplSeq;
    OBB_MGT_RIIterator_RIInfo* pImplInfo = NULL;

    while (1)
    {
        // Get the next impl (includes name and uuids)
        if ( (pImplInfo = GetNextImpl(Iterator, &ImplSeq)) == NULL)
        {
            // If we're here we either ran out of impls
            // or an exception occured.
            bStatus = TRUE;
            break;
        }

        // Add impl info data to list
        CImplEntry* pEntry = new CImplEntry;

        pEntry->m_strImplName = pImplInfo->Name;
        pEntry->m_strInstUUID = pImplInfo->InstUUID;
        pEntry->m_strImplUUID = pImplInfo->ImplUUID;
        pEntry->m_objRunningImpl = pImplInfo->RunningImpl;

        // Get the attributes for the impl just returned
        if (!GetImplAttributes(pImplInfo->RunningImpl, pEntry))
        {
            // This shouldn't happen?
            bStatus = FALSE;
            break;
        }

#if 0
        TRACE("\n   Implementation Name\n");
        TRACE("-------------------------------------------\n");
        TRACE("   %s\n", pEntry->m_strImplName);
        TRACE("   Inst UUID: %s\n", pEntry->m_strInstUUID);
        TRACE("   Impl UUID: %s\n", pEntry->m_strImplUUID);
        TRACE("   State:     %s\n", pEntry->m_strState);
#endif
        m_ImplList.AddTail(pEntry);

    } // while (TRUE)

    // Free memory for sequence buffer
    CORBA_free(pImplInfo);

    // Destroy the iterator
    OBB_MGT_RIIterator_destroy(Iterator, NULL);

    DisplayImpls();

    return bStatus;
}

#define NUMBER_COLUMNS 4
char* grColumnNames[] = { "Impl Name", "State", "Select State", "PID" };
int grColumnWidths[] = { 250, 100, 100, 100 };

void CAgent::InitializeListCtrl(CListCtrl* pListCtrl)
{
    // Save for future use
    m_pListCtrl = pListCtrl;

    // Initialize the list control to hold the implementations
    int nResult = 0;
    LV_COLUMN lvC;

    // Use same mask for all columns
    lvC.mask     = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    lvC.fmt      = LVCFMT_LEFT;

    for (int nIndex = 0; nIndex < NUMBER_COLUMNS; nIndex++)
    {
        lvC.iSubItem = nIndex;
        lvC.pszText = grColumnNames[nIndex];
        lvC.cx = grColumnWidths[nIndex];

        nResult = m_pListCtrl->InsertColumn(nIndex, &lvC);
    }
}

void CAgent::DisplayImpls(void)
{
    if (m_objAgent == NULL)
        return;

    POSITION Position = 0;
    int nIndex = 0;
    for (Position = m_ImplList.GetHeadPosition(); Position != NULL; nIndex++)
    {
        LV_ITEM lvI;
        CImplEntry* pImplEntry = NULL;

        pImplEntry = (CImplEntry *) m_ImplList.GetNext(Position);

        lvI.mask       = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
        lvI.iItem      = nIndex;
        lvI.iSubItem   = 0;
        lvI.state      = 0;
        lvI.stateMask  = 0;
	    lvI.pszText    = LPSTR_TEXTCALLBACK;
	    lvI.cchTextMax = 256;
        lvI.lParam     = (LPARAM) pImplEntry;
        
		ASSERT(m_pListCtrl->InsertItem(&lvI) != -1);
        ASSERT(m_pListCtrl->SetItemText(nIndex, 1, LPSTR_TEXTCALLBACK));
        ASSERT(m_pListCtrl->SetItemText(nIndex, 2, LPSTR_TEXTCALLBACK));
        ASSERT(m_pListCtrl->SetItemText(nIndex, 3, LPSTR_TEXTCALLBACK));
	}
}


void CAgent::GetDisplayInfo(NMHDR* pNMHDR) 
{
    if (m_objAgent == NULL)
        return;

    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
    CImplEntry* pEntry = (CImplEntry*)(pDispInfo->item.lParam);

    switch (pDispInfo->item.iSubItem)
    {
        case 0:
            strcpy(m_szSelText, pEntry->m_strImplName);
            pDispInfo->item.pszText = m_szSelText;
            break;

        case 1:
            strcpy(m_szSelText, pEntry->m_strState);
            pDispInfo->item.pszText = m_szSelText;
            break;

        case 2:
            strcpy(m_szSelText, pEntry->m_strSelectState);
            pDispInfo->item.pszText = m_szSelText;
            break;

        case 3:
            // Not implemented yet
            //strcpy(m_szSelText, pEntry->m_strPID);
            //pDispInfo->item.pszText = m_szSelText;
            break;

        default:
            break;
    }
}

2431.5Notes on the source filesMIASYS::DLUGOSZMy reality check just bouncedTue Feb 11 1997 15:5731
    Ok, I've posted the code - this is an MFC extension DLL. A few quick
    notes:
    
      o  CEnvironment is a class derived from CORBA_Environment. It is in
         a different DLL (since I don't want to load OBBAGENT unless I 
         really need it since the OBB management DLL causes rebasing).
    
      o  The code that kick off listing of impls and generates the 
         exception is as follows:
    
         BOOL CORBManageDoc::GetImpls()
         {
             if (!m_bHaveAgent)
             {
                 TRACE("Initialize Agent object");
                 if (m_Agent.GetAgent("eagle"))
                     m_bHaveAgent = TRUE; 
                 else
                     return FALSE;
             }
    
             BOOL bStatus = m_Agent.GetImpls();
             return bStatus;
         }
    
         m_bHaveAgent is initialized to FALSE in the document constructor
         and the node name is currently wired to "eagle" which is the 
         local host.
    
    Ron
    
2431.6PTR 16-3-237REQUE::BOWERPeter Bower, ObjectBrokerSun Feb 23 1997 07:367
    
    I have entered this as a problem report.
    
    Try releasing the agent object before spawning net stop of the agent. If 
    possible, you might even want to call rundown to release all the
    obb resources. 
    
2431.7Are there any ORB resources?MIASYS::DLUGOSZMy reality check just bouncedMon Feb 24 1997 16:317
    Since the agent routines don't appear to touch the ORB are there
    any ORB resources to release?
    
    It appears, at least, that the agent routines talk directly to the
    agent - bypassing the ORB.
    
    Ron
2431.8REQUE::BOWERPeter Bower, ObjectBrokerMon Feb 24 1997 20:558
    
    It appears that there is a transport connection to the agent that
    is cached. When the agent is shutdown and restarted, an attempt to
    use the connection fails. Releasing the agent object before the
    shutdown might release the handle. Calling rundown will definitely
    release the handle as it releases all OBB resources.
    
    
2431.9The rundown did it....MIASYS::DLUGOSZMy reality check just bouncedWed Feb 26 1997 10:385
    Releasing the agent before stopping it had no effect. Running down the
    ORB did the trick.
    
    Thanks Peter,
    Ron