Back to home page

Enduro/X

 
 

    


0001 #!/usr/bin/pscript
0002 
0003 userlog("Generate go client");
0004 
0005 //Include wizard base.
0006 compilestring(getwizardbase())();
0007 
0008 //Provision class
0009 class GoClient extends WizardBase {
0010 
0011         constructor()
0012         {
0013                 base.constructor();
0014         }
0015         
0016 
0017         //Configure it:
0018         </ order=0, name = "XATMI Client Name (binary)", type = "string", min=1, max=512 /> 
0019         cltname = "testcl";
0020         
0021         </ order=1, name = "Use UBF?", type = "yn"/> 
0022         useubf = "y";
0023         
0024         </ order=2, name = "UBF package name", 
0025                 type = "path" depend="(::prov.useubf==\"y\")" /> 
0026         ubfname = "ubftab";
0027         
0028         </ order=3, name = "Gen makefile", type = "yn"/> 
0029         genmake = "y";
0030         
0031         </ order=4, name = "INI File section (optional, will read config if set)", 
0032                 type = "string", depend="(::prov.useubf==\"y\")", min=0/> 
0033         config = "";
0034         
0035         goClientFile = "";
0036         
0037         makeFile = "";
0038         
0039         function getOutputFiles()
0040         {
0041                 goClientFile=appHome+"/"+cltname+".go";
0042                 makeFile=appHome+"/Makefile";
0043         }
0044         
0045         ////////////////////////////////////////////////////////////////////////
0046         //Build Go Client code
0047         ////////////////////////////////////////////////////////////////////////
0048         goClientVal = "";
0049         function buildClient()
0050         {
0051         
0052                 goClientVal = @"package main
0053 
0054 import (
0055         ""errors""
0056         ""fmt""
0057         ""os""
0058         atmi ""github.com/endurox-dev/endurox-go""
0059 "+(useubf=="y"?"\tu \""+ubfname+"\"\n":"")+@")
0060 
0061 /*
0062 #include <signal.h>
0063 */
0064 import ""C""
0065 
0066 const (
0067         ProgSection = """+cltname+@"""
0068 )
0069 
0070 var MSomeConfigFlag string = """"
0071 var MSomeOtherConfigFlag int = 0
0072 
0073 //Run the listener
0074 func apprun(ac *atmi.ATMICtx) error {
0075 
0076         //Do some work here
0077 "+(useubf=="y"?@"
0078         buf, err := ac.NewUBF(1024)
0079 
0080         if err != nil {
0081                 return errors.New(err.Error());
0082         }
0083         
0084         //Set some field for call
0085         if err := buf.BChg(u.T_STRING_FLD, 0, ""Hello world!""); nil != err {
0086                 return errors.New(err.Error());
0087         }
0088         
0089         //Call the server
0090         if _, err := ac.TpCall(""TESTSV"", buf, 0); nil != err {
0091                 return errors.New(err.Error());
0092         }
0093         
0094         //Print response
0095         buf.TpLogPrintUBF(atmi.LOG_DEBUG, ""Got response"")
0096         
0097 "
0098 :"")+@"
0099 
0100         return nil
0101 }
0102 
0103 //Init function
0104 //@param ac     ATMI context
0105 //@return error (if erro) or nil
0106 func appinit(ac *atmi.ATMICtx) error {
0107 
0108         if err := ac.TpInit(); err != nil {
0109                 return errors.New(err.Error())
0110         }
0111 
0112 "+(config!=""?@"//Get the configuration
0113         buf, err := ac.NewUBF(16 * 1024)
0114         if nil != err {
0115                 ac.TpLogError(""Failed to allocate buffer: [%s]"", err.Error())
0116                 return errors.New(err.Error())
0117         }
0118 
0119         //If we have a command line flag, then use it
0120         //else use CCTAG from env
0121         buf.BChg(u.EX_CC_CMD, 0, ""g"")
0122 
0123         subSection := """"
0124 
0125         if len(os.Args) > 1 {
0126                 subSection = os.Args[1]
0127                 ac.TpLogInfo(""Using subsection from command line: [%s]"", subSection)
0128         } else {
0129                 subSection = os.Getenv(""NDRX_CCTAG"")
0130                 ac.TpLogInfo(""Using subsection from environment NDRX_CCTAG: [%s]"",
0131                         subSection)
0132         }
0133 
0134         buf.BChg(u.EX_CC_LOOKUPSECTION, 0, fmt.Sprintf(""%s/%s"", ProgSection, subSection))
0135 
0136         if _, err := ac.TpCall(""@CCONF"", buf, 0); nil != err {
0137                 ac.TpLogError(""ATMI Error %d:[%s]"", err.Code(), err.Message())
0138                 return errors.New(err.Error())
0139         }
0140 
0141         buf.TpLogPrintUBF(atmi.LOG_DEBUG, ""Got configuration."")
0142 
0143         //Set the parameters
0144         occs, _ := buf.BOccur(u.EX_CC_KEY)
0145         // Load in the config...
0146         for occ := 0; occ < occs; occ++ {
0147                 ac.TpLog(atmi.LOG_DEBUG, ""occ %d"", occ)
0148                 fldName, err := buf.BGetString(u.EX_CC_KEY, occ)
0149 
0150                 if nil != err {
0151                         ac.TpLog(atmi.LOG_ERROR, ""Failed to get field ""+
0152                                 ""%d occ %d"", u.EX_CC_KEY, occ)
0153                         return errors.New(err.Error())
0154                 }
0155 
0156                 ac.TpLog(atmi.LOG_DEBUG, ""Got config field [%s]"", fldName)
0157 
0158                 switch fldName {
0159 
0160                 case ""some_config_flag"":
0161                         MSomeConfigFlag, _ = buf.BGetString(u.EX_CC_VALUE, occ)
0162                         ac.TpLogInfo(""Got [%s] = [%s]"", fldName, MSomeConfigFlag)
0163                         break
0164                 case ""some_other_flag"":
0165                         MSomeOtherConfigFlag, _ = buf.BGetInt(u.EX_CC_VALUE, occ)
0166                         ac.TpLogInfo(""Got [%s] = [%d]"", fldName, MSomeOtherConfigFlag)
0167                         break
0168                 case ""gencore"":
0169                         gencore, _ := buf.BGetInt(u.EX_CC_VALUE, occ)
0170 
0171                         if 1 == gencore {
0172                                 //Process signals by default handlers
0173                                 ac.TpLogInfo(""gencore=1 - SIGSEG signal will be "" +
0174                                         ""processed by default OS handler"")
0175                                 // Have some core dumps...
0176                                 C.signal(11, nil)
0177                         }
0178                         break
0179                 case ""debug"":
0180                         //Set debug configuration string
0181                         debug, _ := buf.BGetString(u.EX_CC_VALUE, occ)
0182                         ac.TpLogDebug(""Got [%s] = [%s] "", fldName, debug)
0183                         if err := ac.TpLogConfig((atmi.LOG_FACILITY_NDRX | atmi.LOG_FACILITY_UBF | atmi.LOG_FACILITY_TP),
0184                                 -1, debug, ""TCPG"", """"); nil != err {
0185                                 ac.TpLogError(""Invalid debug config [%s] %d:[%s]"",
0186                                         debug, err.Code(), err.Message())
0187                                 return errors.New(err.Message())
0188                         }
0189 
0190                 default:
0191                         ac.TpLogInfo(""Unknown flag [%s] - ignoring..."", fldName)
0192                         break
0193                 }
0194         }":"")+@"
0195 
0196         return nil
0197 }
0198 
0199 //Un-init & Terminate the application
0200 //@param ac     ATMI Context
0201 //@param restCode       Return code. atmi.FAIL (-1) or atmi.SUCCEED(0)
0202 func unInit(ac *atmi.ATMICtx, retCode int) {
0203 
0204         ac.TpTerm()
0205         ac.FreeATMICtx()
0206         os.Exit(retCode)
0207 }
0208 
0209 //Cliet process main entry
0210 func main() {
0211 
0212         ac, errA := atmi.NewATMICtx()
0213 
0214         if nil != errA {
0215                 fmt.Fprintf(os.Stderr, ""Failed to allocate cotnext %d:%s!\n"",
0216                         errA.Code(), errA.Message())
0217                 os.Exit(atmi.FAIL)
0218         }
0219 
0220         if err := appinit(ac); nil != err {
0221                 ac.TpLogError(""Failed to init: %s"", err)
0222                 os.Exit(atmi.FAIL)
0223         }
0224 
0225         ac.TpLogWarn(""Init complete, processing..."")
0226 
0227         if err := apprun(ac); nil != err {
0228                 unInit(ac, atmi.FAIL)
0229         }
0230 
0231         unInit(ac, atmi.SUCCEED)
0232 }
0233 
0234 ";      
0235         }
0236 
0237         ////////////////////////////////////////////////////////////////////////
0238         //Client END
0239         ////////////////////////////////////////////////////////////////////////
0240         
0241         
0242         ////////////////////////////////////////////////////////////////////////
0243         //Build makefile
0244         ////////////////////////////////////////////////////////////////////////
0245         
0246         makeFileVal = "";
0247         function buildMakefile()
0248         {
0249         
0250                 makeFileVal = @"
0251 SOURCEDIR=.
0252 SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
0253 
0254 BINARY="+cltname+@"
0255 LDFLAGS=
0256 
0257 VERSION=1.0.0
0258 BUILD_TIME=`date +%FT%T%z`
0259 
0260 .DEFAULT_GOAL: $(BINARY)
0261 
0262 $(BINARY): $(SOURCES)
0263         go build ${LDFLAGS} -o ${BINARY} *.go
0264 
0265 .PHONY: install
0266 install:
0267         go install ${LDFLAGS} ./...
0268 
0269 .PHONY: clean
0270 clean:
0271         if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
0272 ";
0273         }
0274         
0275         
0276         ////////////////////////////////////////////////////////////////////////
0277         //Build makefile, END
0278         ////////////////////////////////////////////////////////////////////////
0279         
0280 }
0281         
0282 
0283 //Run the mater installer
0284 function install() 
0285 {
0286         local root = getroottable();
0287 
0288         //Create a provision object
0289         root["prov"] <- GoClient();
0290 
0291         if (!::prov.isDefaulted)
0292         {
0293                 ::prov.runInteractive();
0294         }
0295 
0296         if (::prov.validatAndPrintConfig())
0297         {
0298                 ::prov.getOutputFiles();
0299                 ::prov.buildClient();
0300 
0301                 if (!::prov.writeFile(::prov.goClientFile, ::prov.goClientVal))
0302                 {
0303                         return false;
0304                 }
0305                 
0306                 //Build makefile if needed...
0307                 if ("y"==::prov.genmake)
0308                 {
0309                         ::prov.buildMakefile();
0310                         
0311                         if (!::prov.writeFile(::prov.makeFile, ::prov.makeFileVal))
0312                         {
0313                                 return false;
0314                         }
0315                 }
0316         }
0317         else
0318         {
0319                 return false;
0320         }
0321 
0322         return true;
0323 }
0324 
0325 if (::install())
0326 {
0327         print("Go client gen ok!\n");
0328         
0329         return 0;
0330 }
0331 else
0332 {
0333         print("Go client gen failed!\n");
0334         return -1;
0335 }