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 }