/* pi_wrapper.c -- Wrappers for the FEWS PI service */ #include #include /* Define some helper variables and functions */ Tcl_Interp *interp; void TearDown () {Tcl_Finalize();} int EvalFile (char *fileName) { return Tcl_EvalFile(interp, fileName); } int Init (char *argv0) { char *pchar; char buffer[1000]; /* Initialise the library itself */ Tcl_FindExecutable(argv0); interp = Tcl_CreateInterp(); if (Tcl_Init(interp) != TCL_OK) { fprintf( stderr, "Error at start up:\n%s\n", Tcl_GetStringResult(interp) ); exit(1); } } void InitPiService( char *hostname, int port ) { char buffer[10]; char *startUpCode; sprintf( buffer, "%d", port ); Tcl_SetVar( interp, "hostname", hostname, 0 ); Tcl_SetVar( interp, "port", buffer, 0 ); /* Initialise the FEWS PI services This is simply embedded Tcl code. It reduces the number of dependencies of the program */ startUpCode = "\ #\n\ # Set up the services: one Tcl command for each method\n\ #\n\ \n\ package require SOAP\n\ \n\ ::SOAP::create getClientConfigFile -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {fileName string\n\ fileExtension string}\n\ \n\ ::SOAP::create getSystemTime -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string}\n\ \n\ ::SOAP::create getLogMessages -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ taskId string}\n\ \n\ ::SOAP::create getAvailableStateTimes -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ id string}\n\ \n\ ::SOAP::create getColdStateIds -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ id string}\n\ \n\ ::SOAP::create getEnsembleMemberIndices -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ ensembleId string}\n\ \n\ ::SOAP::create getModuleStateBinary -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ id string\n\ stateTime dateTime\n\ ensembleId string\n\ ensembleMemberIndex int}\n\ \n\ ::SOAP::create getLocations -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string}\n\ \n\ ::SOAP::create createTask -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string}\n\ \n\ ::SOAP::create getTimeSeries -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ id string\n\ taskId string\n\ startTime dateTime\n\ timeZero dateTime\n\ endTime dateTime\n\ parameterIds string()\n\ locationIds string()\n\ ensembleId string\n\ ensembleMemberIndex int\n\ includeThresholds boolean}\n\ \n\ #\n\ # This method is not implemented on the FEWS side\n\ #\n\ ::SOAP::create getTimeSeriesBytes -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ id string\n\ taskId string\n\ startTime dateTime\n\ timeZero dateTime\n\ endTime dateTime\n\ parameterIds string()\n\ locationIds string()\n\ ensembleId string\n\ ensembleMemberIndex int\n\ includeThresholds boolean}\n\ \n\ #\n\ # Methods for running tasks\n\ #\n\ ::SOAP::create createTask -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string}\n\ \n\ ::SOAP::create runTask -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ taskId string\n\ workflowId string\n\ startTime dateTime\n\ timeZero dateTime\n\ endTime dateTime\n\ coldStateId string\n\ scenarioId string\n\ userId string\n\ description string}\n\ \n\ ::SOAP::create waitForTask -uri Fews -proxy http://$hostname:$port/FewsPiService \\\n\ -parameters {clientId string\n\ taskRunId string\n\ waitMillis int}\n"; if ( Tcl_Eval( interp, startUpCode ) != TCL_OK ) { fprintf( stderr, "Error at start up:\n%s\n", Tcl_GetStringResult(interp) ); exit(1); } } /* Fews PI services: wrapper functions */ char *getClientConfigFile( char *fileName, char *fileExtension ) { char buffer[1000]; sprintf( buffer, "getClientConfigFile \"%s\" \"%s\"", fileName, fileExtension ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getSystemTime( char *clientId ) { char buffer[1000]; sprintf( buffer, "getSystemTime \"%s\"", clientId ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getLogMessages( char *clientId, char *taskId ) { char buffer[1000]; sprintf( buffer, "getLogMessages \"%s\" \"%s\"", clientId, taskId ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getAvailableStateTimes( char *clientId, char *id ) { char buffer[1000]; sprintf( buffer, "getAvailableStateTimes \"%s\" \"%s\"", clientId, id ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getColdStateIds( char *clientId, char *id ) { char buffer[1000]; sprintf( buffer, "getColdStateIds \"%s\" \"%s\"", clientId, id ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getEnsembleMemberIndices( char *clientId, char *id ) { char buffer[1000]; sprintf( buffer, "getEnsembleMemberIndices \"%s\" \"%s\"", clientId, id ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getModuleStateBinary( char *clientId, char *id, char *stateTime, char *ensembleId, int ensembleMemberIndex, int *size ) { char buffer[1000]; char *binary; char *result; Tcl_Obj *binaryObj; sprintf( buffer, "getModuleStateBinary \"%s\" \"%s\" %s %s %d", clientId, id, stateTime, (ensembleId == NULL? "null" : ensembleId), ensembleMemberIndex ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { binaryObj = Tcl_GetObjResult( interp ) ; binary = Tcl_GetStringFromObj( binaryObj, size ); result = (char *) malloc( sizeof(char) *(*size) ) ; memcpy( result, binary, (*size) ); return result; } } char *getLocations( char *clientId ) { char buffer[1000]; sprintf( buffer, "getLocations \"%s\"", clientId ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *getTimeSeries( char *clientId, char *id, char *taskId, char *startTime, char *timeZero, char *endTime, char *parameterIds[], int nParameters, char *locationIds[], int nLocations, char *ensembleId, int ensembleMemberIndex, int includeThresholds) { int i; int objc = 12; Tcl_Obj *objv[12]; Tcl_Obj **elemObjv; /* Use Tcl_Obj interface because of the large number of arguments */ objv[0] = Tcl_NewStringObj( "getTimeSeries", -1 ); objv[1] = Tcl_NewStringObj( clientId, -1 ); objv[2] = Tcl_NewStringObj( id, -1 ); if ( taskId != NULL ) { objv[3] = Tcl_NewStringObj( taskId, -1 ); } else { objv[3] = Tcl_NewStringObj( "null", -1 ); } objv[4] = Tcl_NewStringObj( startTime, -1 ); objv[5] = Tcl_NewStringObj( timeZero, -1 ); objv[6] = Tcl_NewStringObj( endTime, -1 ); /* List of parameters ... */ elemObjv = (Tcl_Obj **) malloc( sizeof(Tcl_Obj *) * nParameters ); for ( i = 0; i < nParameters; i ++ ) { elemObjv[i] = Tcl_NewStringObj( parameterIds[i], -1 ); } objv[7] = Tcl_NewListObj( nParameters, elemObjv ); free( elemObjv ); /* List of locations ... */ elemObjv = (Tcl_Obj **) malloc( sizeof(Tcl_Obj *) * nLocations ); for ( i = 0; i < nLocations; i ++ ) { elemObjv[i] = Tcl_NewStringObj( locationIds[i], -1 ); } objv[8] = Tcl_NewListObj( nLocations, elemObjv ); /* The rest ... */ if ( ensembleId != NULL ) { objv[9] = Tcl_NewStringObj( ensembleId, -1 ); } else { objv[9] = Tcl_NewStringObj( "null", -1 ); } objv[10] = Tcl_NewIntObj( ensembleMemberIndex ); objv[11] = Tcl_NewBooleanObj( includeThresholds ); for ( i = 0; i < 12; i ++ ) { Tcl_IncrRefCount( objv[i] ) ; } /* Note: we should probably look into the management of the elements of the two lists ... */ if ( Tcl_EvalObjv( interp, objc, objv, 0 ) != TCL_OK ) { for ( i = 0; i < objc; i ++ ) { Tcl_DecrRefCount( objv[i] ) ; } fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { for ( i = 0; i < objc; i ++ ) { Tcl_DecrRefCount( objv[i] ) ; } return Tcl_GetStringResult( interp ) ; } } char *createTask( char *clientId ) { char buffer[1000]; sprintf( buffer, "createTask \"%s\"", clientId ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { return Tcl_GetStringResult( interp ) ; } } char *runTask( char *clientId, char *taskId, char *workflowId, char *startTime, char *timeZero, char *endTime, char *coldStateId, char *scenarioId, char *userId, char *description ) { int i; int objc = 11; Tcl_Obj *objv[11]; /* Use Tcl_Obj interface because of the large number of arguments */ objv[0] = Tcl_NewStringObj( "runTask", -1 ); objv[1] = Tcl_NewStringObj( clientId, -1 ); objv[2] = Tcl_NewStringObj( taskId, -1 ); objv[3] = Tcl_NewStringObj( workflowId, -1 ); objv[4] = Tcl_NewStringObj( startTime, -1 ); objv[5] = Tcl_NewStringObj( timeZero, -1 ); objv[6] = Tcl_NewStringObj( endTime, -1 ); if ( coldStateId != NULL ) { objv[7] = Tcl_NewStringObj( coldStateId, -1 ); } else { objv[7] = Tcl_NewStringObj( "null", -1 ); } if ( scenarioId != NULL ) { objv[8] = Tcl_NewStringObj( scenarioId, -1 ); } else { objv[8] = Tcl_NewStringObj( "null", -1 ); } objv[9] = Tcl_NewStringObj( userId, -1 ); objv[10] = Tcl_NewStringObj( description, -1 ); for ( i = 0; i < 11; i ++ ) { Tcl_IncrRefCount( objv[i] ) ; } if ( Tcl_EvalObjv( interp, objc, objv, 0 ) != TCL_OK ) { for ( i = 0; i < objc; i ++ ) { Tcl_DecrRefCount( objv[i] ) ; } fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return NULL; } else { for ( i = 0; i < objc; i ++ ) { Tcl_DecrRefCount( objv[i] ) ; } return Tcl_GetStringResult( interp ) ; } } int waitForTask( char *clientId, char *taskRunId, int waitMillis ) { int success; Tcl_Obj *resultObj; char buffer[1000]; sprintf( buffer, "waitForTask \"%s\" \"%s\" %d", clientId, taskRunId, waitMillis ); if ( Tcl_Eval( interp, buffer ) != TCL_OK ) { fprintf( stderr, "Error: %s\n", Tcl_GetStringResult(interp) ); return 0; } else { resultObj = Tcl_GetObjResult( interp ) ; Tcl_GetBooleanFromObj( interp, resultObj, &success ); return success; } } /* * Auxiliary functions */ char *getElement( char *list, int index ) { char *elem; Tcl_Obj *listObj; Tcl_Obj *obj; listObj = Tcl_NewStringObj( list, -1 ); Tcl_IncrRefCount( listObj ); if ( Tcl_ListObjIndex( interp, listObj, index, &obj ) != TCL_OK ) { Tcl_DecrRefCount( listObj ); return NULL; } else { elem = Tcl_GetString( obj ); Tcl_DecrRefCount( obj ); Tcl_DecrRefCount( listObj ); return elem; } }