int main(int argc, char *argv[])
{
    SaAisErrorT rc = SA_AIS_OK;
    SaSelectionObjectT dispatch_fd;
    fd_set read_fds;
    ClRcT ret = CL_OK;

    /* Connect to the SAF cluster */
    initializeAmf();

    /* Do the application specific initialization here. */
    FD_ZERO(&read_fds);

    if ( (rc = saAmfSelectionObjectGet(amfHandle, &dispatch_fd)) != SA_AIS_OK)
        errorExit(rc);
    
    FD_SET(dispatch_fd, &read_fds);
    
    /* Handle the AMF dispatch loop by spawning a thread that does it */
    ret = clOsalTaskCreateDetached("DISPATCH-THREAD", CL_OSAL_SCHED_OTHER, 0, 0, saAmfDispatchThread, NULL);
    if(ret != CL_OK)
    {
        clprintf(CL_LOG_SEV_ERROR, "Dispatch task create failed with rc 0x%x",rc);
        return ret;
    } 
    while (!unblockNow)
    {
        /* csa112: If I am active then I'll publish an event.
           Note, any application can publish and event regardless of
           HA state.  This tutorial simply uses HA state so only
           one of the two processes are publishing.
        */
        
        if (running && ha_state == SA_AMF_HA_ACTIVE)
        {
            csa113Comp_PublishEvent();
        }
    
        sleep(1);  /* Keep the event publish rate reasonable for this tutorial*/
    }
    
    /* Do the application specific finalization here. */
    if ((rc = saEvtChannelClose(evtChannelHandle)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_SEV_ERROR, "Failed [0x%x] to close event channel", rc);
    }

    if ((rc = saEvtFinalize(evtLibHandle)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_SEV_ERROR, "Failed [0x%x] to finalize event library", rc);
    }

    /* Now finalize my connection with the SAF cluster */
    if((rc = saAmfFinalize(amfHandle)) != SA_AIS_OK)
      clprintf (CL_LOG_SEV_ERROR, "AMF finalization error[0x%X]", rc);
    else
      clprintf (CL_LOG_SEV_INFO, "AMF Finalized");   

    return 0;
}
void tet_saEvtFinalize(SaEvtHandleT *ptrEvtHandle)
{
  static int try_again_count;
  gl_rc=saEvtFinalize(*ptrEvtHandle);
  WHILE_TRY_AGAIN(gl_rc)
    {
      ++try_again_count;
      if(try_again_count==MAX_NUM_TRY_AGAINS)
      {
        printf("\n Finalize API Crossed Max Try Agains: exiting \n");
        break;
      }
      RETRY_SLEEP; 
      gl_rc=saEvtFinalize(*ptrEvtHandle);
      if(gl_rc==SA_AIS_OK)
        printf("\n Finalize Try Again Count = %d\n",try_again_count);
    }
  resultSuccess("saEvtFinalize() invoked",gl_rc);
}
void
test_pub()
{
	SaEvtHandleT handle;
	SaEvtChannelHandleT channel_handle;
	SaEvtEventHandleT event_handle;
	SaEvtChannelOpenFlagsT flags;
	SaNameT channel_name;
	uint64_t test_retention;
	SaSelectionObjectT fd;
	int i;
	struct timeval tv1, tv2, tv_elapsed;
	int write_count = 10000;
	int write_size = user_data_size;


	SaEvtEventIdT event_id;
#ifdef EVENT_SUBSCRIBE
	struct pollfd pfd;
	int nfd;
	int timeout = 1000;
#endif


	
	int result;
	 
	flags = SA_EVT_CHANNEL_PUBLISHER |
#ifdef EVENT_SUBSCRIBE
		SA_EVT_CHANNEL_SUBSCRIBER |
#endif
		SA_EVT_CHANNEL_CREATE;
	strcpy((char *)channel_name.value, channel);
	channel_name.length = strlen(channel);


	result = saEvtInitialize (&handle, &callbacks, &version);
	if (result != SA_AIS_OK) {
		printf("Event Initialize result: %d\n", result);
		exit(1);
	}
	result = saEvtChannelOpen(handle, &channel_name, flags, 
			SA_TIME_MAX, &channel_handle);
	if (result != SA_AIS_OK) {
		printf("channel open result: %d\n", result);
		goto evt_fin;
	}

	/*
	 * Publish with pattens
	 */
	printf("Publish\n");

#ifdef EVENT_SUBSCRIBE
	result = saEvtEventSubscribe(channel_handle,
			&subscribe_filters,
			subscription_id);

	if (result != SA_AIS_OK) {
		printf("event subscribe result: %d\n", result);
		result = saEvtChannelClose(channel_handle);
		if (result != SA_AIS_OK) 
			printf("Channel close result: %d\n", result);
		result = saEvtFinalize(handle);
		if (result != SA_AIS_OK) 
			printf("Finalize result: %d\n", result);
		return;
	}
#endif
	result = saEvtEventAllocate(channel_handle, &event_handle);
	if (result != SA_AIS_OK) {
		printf("event Allocate result: %d\n", result);
		goto evt_free;
	}

	strcpy((char *)test_pub_name.value, pubname);
	test_pub_name.length = strlen(pubname);
	test_retention = ret_time;
	result = saEvtEventAttributesSet(event_handle,
			&evt_pat_set_array,
			TEST_PRIORITY,
			test_retention,
			&test_pub_name);
	if (result != SA_AIS_OK) {
		printf("event set attr result(2): %d\n", result);
		goto evt_free;
	}

	gettimeofday (&tv1, NULL);
	for (i = 0; i < write_count; i++) {
		result = saEvtEventPublish(event_handle, user_data, 
						write_size, &event_id);
		if (result != SA_AIS_OK) {
			printf("event Publish result(2): %d\n", result);
			goto evt_close;
		}
	}
	gettimeofday (&tv2, NULL);
	timersub (&tv2, &tv1, &tv_elapsed);

	printf ("%5d Writes ", write_count);
	printf ("%5d bytes per write ", write_size);
	printf ("%7.3f Seconds runtime ",
		(tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
	printf ("%9.3f TP/s ",
		((float)write_count) /  (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
	printf ("%7.3f MB/s.\n",
		((float)write_count) * ((float)write_size) /  ((tv_elapsed.tv_sec + (
		tv_elapsed.tv_usec / 1000000.0)) * 1000000.0));

exit (1);
	printf("Published event ID: %llx\n", (unsigned long long)event_id);

	/*
	 * See if we got the event
	 */
	result = saEvtSelectionObjectGet(handle, &fd);
	if (result != SA_AIS_OK) {
		printf("saEvtSelectionObject get %d\n", result);
		/* error */
		return;
	}
#ifdef EVENT_SUBSCRIBE
	pfd.fd = fd;
	pfd.events = POLLIN;
	nfd = poll(&pfd, 1, timeout);
	if (nfd <= 0) {
		printf("poll fds %d\n", nfd);
		if (nfd < 0) {
			perror("poll error");
		}
		goto evt_free;
	}

	printf("Got poll event\n");
	result = saEvtDispatch(handle, SA_DISPATCH_ONE);
	if (result != SA_AIS_OK) {
		printf("saEvtDispatch %d\n", result);
		goto evt_fin;
	}
#endif


	/*
	 * Test cleanup
	 */
evt_free:
	result = saEvtEventFree(event_handle);
	if (result != SA_AIS_OK) {
		printf("event free result: %d\n", result);
	}

evt_close:
	result = saEvtChannelClose(channel_handle);
	
	if (result != SA_AIS_OK) {
		printf("channel close result: %d\n", result);
	}
evt_fin:
	result = saEvtFinalize(handle);

	if (result != SA_AIS_OK) {
		printf("Event Finalize result: %d\n", result);
	}
	printf("Done\n");

}
int main(int argc, char **argv)
{

    int ioc_address_local = LOCAL_ADDRESS;
    ClRcT rc = CL_OK;
    rc = clExtInitialize(ioc_address_local);
    if (rc != CL_OK)
    {
        printf("Error: failed to Initialize SAFplus libraries\n");
        exit(1);
    }

    nodeCacheWait();

    // Demonstrate logging */
    printf("\n\nOpen a global log stream and write several records to active PY node\n");        
    if ((rc=logInitialize()) == CL_OK)
    {
        printf("log Initialized\n"); 
        logWrite(CL_LOG_SEV_NOTICE,"This is a test of an external app doing logging");
        for(int i=0;i<100;i++)
        {
            ClTimerTimeOutT delay;
            delay.tsSec = 0;
            delay.tsMilliSec = 10; 
            logWrite(CL_LOG_SEV_NOTICE,"external app log %d", i);
            clOsalTaskDelay(delay);            
        }            
    }
    else
    {
        printf("Unable to open log.  Error 0x%x\n",rc);
        return rc;
    }



    //  Open a subscribe event channel and start receiving events.
    printf("\n\nOpen an Event subscription\n");        
    const SaEvtCallbacksT evtCallbacks =
    {
        NULL,
        appEventCallback
    };
    SaVersionT  evtVersion = CL_EVENT_VERSION;
    rc = saEvtInitialize(&evtHandle, &evtCallbacks, &evtVersion);
    if (rc != SA_AIS_OK)
    {
        printf("Failed to init event mechanism [0x%x]\n",rc);
        return rc;
    }

    saNameSet(&evtChannelName,EVENT_CHANNEL_NAME);
    rc = saEvtChannelOpen(evtHandle,&evtChannelName, (SA_EVT_CHANNEL_SUBSCRIBER | SA_EVT_CHANNEL_CREATE), (SaTimeT)SA_TIME_END, &evtChannelHandle);
    if (rc != SA_AIS_OK)
    {
        printf("Failure opening event channel[0x%x] at %ld\n", rc, time(0L));
        goto errorexit;
    }
    rc = saEvtEventSubscribe(evtChannelHandle, NULL, 1);
    if (rc != SA_AIS_OK)
    {
        printf("Failed to subscribe to event channel [0x%x]\n", rc);
        goto errorexit;
    }
    //open a global log stream and write several records
        
    printf("Open a publisher event channel\n");        
    // open a publisher event channel and 
    openPublisherChannel();
    printf("Start publishing events.\nThe PY component on active PY node subscribes to these events and logs them so you can verify receipt by looking in the clock.log.latest and app.lates  on node active PY node .\n");        
    testEvtMainLoop();
    printf("Unsubscribe event chanel.............................\n");        
    rc = saEvtEventUnsubscribe(evtChannelHandle,1);
    if (rc != SA_AIS_OK) 
        printf("Channel unsubscribe result: %d\n", rc);
    printf("Close subscribe event chanel.............................\n");        
    rc = saEvtChannelClose(evtChannelHandle);
    if (rc != SA_AIS_OK) 
        printf("Channel close result: %d\n", rc);
    printf("Close publish event channel.............................\n");        
    rc = saEvtChannelClose(evtChannelHandlePublic);
    if (rc != SA_AIS_OK) 
        printf("Channel close result: %d\n", rc);
    // never inited: printf("Finalize publish event handle.............................\n");        
    //    saEvtFinalize(gTestInfo.evtInitHandle);
    printf("Finalize xubscribe event handle.............................\n");        
    saEvtFinalize(evtHandle);
    openPublisherChannel();
    testEvtMainLoop();
    printf("Close publish event channel.............................\n");        
    rc = saEvtChannelClose(evtChannelHandlePublic);
    if (rc != SA_AIS_OK) 
        printf("Channel close result: %d\n", rc);
    // never inited printf("Finalize publish event handle.............................\n");        
    //   saEvtFinalize(gTestInfo.evtInitHandle);
    
    return 0;
errorexit:
    printf ("Initialization error [0x%x]\n",rc);
}
int main(int argc, char *argv[])
{
    SaNameT             appName = {0};
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    SaSelectionObjectT dispatch_fd;
    fd_set read_fds;
    
    /*
     * Declare other local variables here.
     */

    /*
     * Get the pid for the process and store it in global variable.
     */

    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */

    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL;
    callbacks.saAmfComponentTerminateCallback   = clCompAppTerminate;
    callbacks.saAmfCSISetCallback               = clCompAppAMFCSISet;
    callbacks.saAmfCSIRemoveCallback            = clCompAppAMFCSIRemove;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /*
     * Initialize AMF client library.
     */

    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK) 
        goto errorexit;

    FD_ZERO(&read_fds);

    /*
     * Get the AMF dispatch FD for the callbacks
     */
    if ( (rc = saAmfSelectionObjectGet(amfHandle, &dispatch_fd)) != SA_AIS_OK)
        goto errorexit;
    
    FD_SET(dispatch_fd, &read_fds);


    /*
     * Do the application specific initialization here.
     */


    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        goto errorexit;
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        goto errorexit;

    /* Open the log stream as soon as I've registered with AMF */
    clEvalAppLogStreamOpen((ClCharT *)appName.value, &gEvalLogStream);

    /* Handle the AMF dispatch loop by spawning a thread that does it */
    rc = clOsalTaskCreateDetached("DISPATCH-THREAD", CL_OSAL_SCHED_OTHER, 0, 0, saAmfDispatchThread, NULL);
    if(rc != CL_OK)
    {
        clprintf(CL_LOG_SEV_ERROR, "Dispatch task create failed with rc 0x%x",rc);
        return rc;
    }
    
    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);

    /* csa112: initialize the event client library, open the event channel and subscribe to events */
    if (1)
    {
        const SaEvtCallbacksT evtCallbacks =
        {
            NULL,  /* Event open callback */
            csa112Comp_appEventCallback  /* Event delivery callback */
        };
        SaVersionT  evtVersion = {(ClUint8T)'B', 0x1, 0x1};
        
        rc = saEvtInitialize(&evtLibHandle, &evtCallbacks, &evtVersion);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_ERROR, "Failed to init event mechanism [0x%x]\n", rc);
            return rc;
        }
            // Open an event chanel so that we can subscribe to events on that channel
        rc = saEvtChannelOpen(evtLibHandle, &evtChannelName, (SA_EVT_CHANNEL_PUBLISHER | SA_EVT_CHANNEL_SUBSCRIBER | SA_EVT_CHANNEL_CREATE), (SaTimeT)SA_TIME_END, &evtChannelHandle);
        if (rc != SA_AIS_OK)
          {
          clprintf(CL_LOG_SEV_ERROR, "Failure opening event channel [0x%x] at %ld", rc, time(0L));
          goto errorexit;
          }
        
      rc = saEvtEventSubscribe(evtChannelHandle, NULL, 1);
      if (rc != SA_AIS_OK)
      {
        clprintf(CL_LOG_SEV_ERROR, "Failed to subscribe to event channel [0x%x]",rc);
        goto errorexit;
      }
    }

    /*csa113: create an event definition to be published */
    if (1)
    {
        SaNameT publisherName;
        clNameSet((ClNameT*) &publisherName,PUBLISHER_NAME);
        
        rc = saEvtEventAllocate(evtChannelHandle, &eventHandle);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_SEV_ERROR, "Failed to allocate event [0x%x]\n", rc);
            assert(0);
        }

        rc = saEvtEventAttributesSet(eventHandle, NULL, 1, 0, &publisherName);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_ERROR, "Failed to set event attributes [0x%x]\n",rc);
            assert(0);            
        }
    }
    
    
    while (!exiting)
    {
        /* csa112: If I am active then I'll publish an event.
           Note, any application can publish and event regardless of
           HA state.  This tutorial simply uses HA state so only
           one of the two processes are publishing.
        */
        
    if (running && ha_state == SA_AMF_HA_ACTIVE)
    {
        csa113Comp_PublishEvent();
    }
    
    sleep(1);  /* Keep the event publish rate reasonable for this tutorial*/
    }
    
    /*
     * Do the application specific finalization here.
     */

    /* csa112: close the event channel, finalize the event client library */
    if ((rc = saEvtChannelClose(evtChannelHandle)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_ERROR, "Failed [0x%x] to close event channel", rc);
    }

    if ((rc = saEvtFinalize(evtLibHandle)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_ERROR, "Failed [0x%x] to finalize event library", rc);
    }

    if((rc = saAmfFinalize(amfHandle)) != SA_AIS_OK)
	{
        clprintf (CL_LOG_SEV_ERROR, "AMF finalization error[0x%X]", rc);
	}

    clprintf (CL_LOG_SEV_INFO, "AMF Finalized");
    
    return 0;

errorexit:

    clprintf (CL_LOG_SEV_ERROR, "Component [%.*s] : PID [%d]. Initialization error [0x%x]\n",
              appName.length, appName.value, mypid, rc);

    return -1;
}