0001 #!/usr/bin/pscript
0002
0003 userlog("Generate go server");
0004
0005 //Include wizard base.
0006 compilestring(getwizardbase())();
0007
0008 //Provision class
0009 class GoServer extends WizardBase {
0010
0011 constructor()
0012 {
0013 base.constructor();
0014 }
0015
0016
0017 //Configure it:
0018 </ order=0, name = "XATMI Server Name (binary)", type = "string", min=1, max=512 />
0019 svname = "testsv";
0020
0021 </ order=1, name = "Service name", type = "string", min=1, max=30 />
0022 svcname = "TESTSV";
0023
0024 </ order=2, name = "Use UBF?", type = "yn"/>
0025 useubf = "y";
0026
0027 </ order=3, name = "UBF package name",
0028 type = "path" depend="(::prov.useubf==\"y\")" />
0029 ubfname = "ubftab";
0030
0031 </ order=4, name = "Gen makefile", type = "yn"/>
0032 genmake = "y";
0033
0034 </ order=5, name = "INI File section (optional, will read config if set)",
0035 type = "string", depend="(::prov.useubf==\"y\")", min=0/>
0036 config = "";
0037
0038 goServerFile = "";
0039
0040 makeFile = "";
0041
0042 function getOutputFiles()
0043 {
0044 goServerFile=appHome+"/"+svname+".go";
0045 makeFile=appHome+"/Makefile";
0046 }
0047
0048 ////////////////////////////////////////////////////////////////////////
0049 //Build the ndrxconfig value
0050 ////////////////////////////////////////////////////////////////////////
0051 goServerVal = "";
0052 function buildServer()
0053 {
0054
0055 goServerVal = @"package main
0056
0057 import (
0058 atmi ""github.com/endurox-dev/endurox-go""
0059 ""fmt""
0060 ""os""
0061 "+(useubf=="y"?"\tu \""+ubfname+"\"\n":"")+@")
0062
0063 const (
0064 SUCCEED = atmi.SUCCEED
0065 FAIL = atmi.FAIL"+(config!=""?"\n\tPROGSECTION = \""+config+"\"":"")+@"
0066 )
0067
0068 //"+svcname+@" service
0069 //@param ac ATMI Context
0070 //@param svc Service call information
0071 func "+svcname+@"(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
0072
0073 ret := SUCCEED
0074
0075 //Return to the caller
0076 defer func() {
0077
0078 ac.TpLogCloseReqFile()
0079 if SUCCEED == ret {
0080 ac.TpReturn(atmi.TPSUCCESS, 0, &svc.Data, 0)
0081 } else {
0082 ac.TpReturn(atmi.TPFAIL, 0, &svc.Data, 0)
0083 }
0084 }()
0085
0086 "+(useubf=="y"?@"
0087 //Get UBF Handler
0088 ub, _ := ac.CastToUBF(&svc.Data)
0089
0090 //Print the buffer to stdout
0091 //fmt.Println(""Incoming request:"")
0092 ub.TpLogPrintUBF(atmi.LOG_DEBUG, ""Incoming request:"")
0093
0094 //Resize buffer, to have some more space
0095 if err := ub.TpRealloc(1024); err != nil {
0096 ac.TpLogError(""TpRealloc() Got error: %d:[%s]"", err.Code(), err.Message())
0097 ret = FAIL
0098 return
0099 }
0100
0101 //Add test field to buffer
0102 if err:=ub.BChg(u.T_STRING_2_FLD, 0, ""Hello World from XATMI server""); err!=nil {
0103 ac.TpLogError(""BChg() Got error: %d:[%s]"", err.Code(), err.Message())
0104 ret = FAIL
0105 return
0106 }
0107
0108 ":"")+@"
0109
0110
0111 //TODO: Run your processing here, and keep the succeed or fail status in
0112 //in ""ret"" flag.
0113
0114 return
0115 }
0116
0117 //Server init, called when process is booted
0118 //@param ac ATMI Context
0119 func Init(ac *atmi.ATMICtx) int {
0120
0121 ac.TpLogWarn(""Doing server init..."");
0122 "+(config!=""?@" if err := ac.TpInit(); err != nil {
0123 return FAIL;
0124 }
0125
0126 //Get the configuration
0127
0128 //Allocate configuration buffer
0129 buf, err := ac.NewUBF(16 * 1024)
0130 if nil != err {
0131 ac.TpLogError(""Failed to allocate buffer: [%s]"", err.Error())
0132 return FAIL
0133 }
0134
0135 buf.BChg(u.EX_CC_CMD, 0, ""g"")
0136 buf.BChg(u.EX_CC_LOOKUPSECTION, 0, fmt.Sprintf(""%s/%s"", PROGSECTION, os.Getenv(""NDRX_CCTAG"")))
0137
0138 if _, err := ac.TpCall(""@CCONF"", buf, 0); nil != err {
0139 ac.TpLogError(""ATMI Error %d:[%s]\n"", err.Code(), err.Message())
0140 return FAIL;
0141 }
0142
0143 //Dump to log the config read
0144 buf.TpLogPrintUBF(atmi.LOG_DEBUG, ""Got configuration."")
0145
0146 occs, _ := buf.BOccur(u.EX_CC_KEY)
0147
0148 // Load in the config...
0149 for occ := 0; occ < occs; occ++ {
0150 ac.TpLogDebug(""occ %d"", occ)
0151 fldName, err := buf.BGetString(u.EX_CC_KEY, occ)
0152
0153 if nil != err {
0154 ac.TpLogError(""Failed to get field ""+
0155 ""%d occ %d"", u.EX_CC_KEY, occ)
0156 return FAIL;
0157 }
0158
0159 ac.TpLogDebug(""Got config field [%s]"", fldName)
0160
0161 switch fldName {
0162
0163 case ""mykey1"":
0164 myval, _ := buf.BGetString(u.EX_CC_VALUE, occ);
0165 ac.TpLogDebug(""Got [%s] = [%s] "", fldName, myval);
0166 break
0167
0168 default:
0169
0170 break
0171 }
0172 }":"")+@"
0173 //Advertize service
0174 if err := ac.TpAdvertise("""+svcname+@""", """+svcname+@""", "+svcname+@"); err != nil {
0175 ac.TpLogError(""Failed to Advertise: ATMI Error %d:[%s]\n"", err.Code(), err.Message())
0176 return atmi.FAIL
0177 }
0178
0179 return SUCCEED
0180 }
0181
0182 //Server shutdown
0183 //@param ac ATMI Context
0184 func Uninit(ac *atmi.ATMICtx) {
0185 ac.TpLogWarn(""Server is shutting down..."");
0186 }
0187
0188 //Executable main entry point
0189 func main() {
0190 //Have some context
0191 ac, err := atmi.NewATMICtx()
0192
0193 if nil != err {
0194 fmt.Fprintf(os.Stderr, ""Failed to allocate new context: %s"", err)
0195 os.Exit(atmi.FAIL)
0196 } else {
0197 //Run as server
0198 if err=ac.TpRun(Init, Uninit); nil!=err {
0199 ac.TpLogError(""Exit with failure"");
0200 os.Exit(atmi.FAIL)
0201 } else {
0202 ac.TpLogInfo(""Exit with success"");
0203 os.Exit(atmi.SUCCEED)
0204 }
0205 }
0206 }
0207 ";
0208 }
0209
0210 ////////////////////////////////////////////////////////////////////////
0211 //Server END
0212 ////////////////////////////////////////////////////////////////////////
0213
0214
0215 ////////////////////////////////////////////////////////////////////////
0216 //Build makefile
0217 ////////////////////////////////////////////////////////////////////////
0218
0219 makeFileVal = "";
0220 function buildMakefile()
0221 {
0222
0223 makeFileVal = @"
0224 SOURCEDIR=.
0225 SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
0226
0227 BINARY="+svname+@"
0228 LDFLAGS=
0229
0230 VERSION=1.0.0
0231 BUILD_TIME=`date +%FT%T%z`
0232
0233 .DEFAULT_GOAL: $(BINARY)
0234
0235 $(BINARY): $(SOURCES)
0236 go build ${LDFLAGS} -o ${BINARY} *.go
0237
0238 .PHONY: install
0239 install:
0240 go install ${LDFLAGS} ./...
0241
0242 .PHONY: clean
0243 clean:
0244 if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
0245 ";
0246 }
0247
0248
0249 ////////////////////////////////////////////////////////////////////////
0250 //Build makefile, END
0251 ////////////////////////////////////////////////////////////////////////
0252
0253 }
0254
0255
0256 //Run the mater installer
0257 function install()
0258 {
0259 local root = getroottable();
0260
0261 //Create a provision object
0262 root["prov"] <- GoServer();
0263
0264 if (!::prov.isDefaulted)
0265 {
0266 ::prov.runInteractive();
0267 }
0268
0269 if (::prov.validatAndPrintConfig())
0270 {
0271 ::prov.getOutputFiles();
0272 ::prov.buildServer();
0273
0274 if (!::prov.writeFile(::prov.goServerFile, ::prov.goServerVal))
0275 {
0276 return false;
0277 }
0278
0279 //Build makefile if needed...
0280 if ("y"==::prov.genmake)
0281 {
0282 ::prov.buildMakefile();
0283
0284 if (!::prov.writeFile(::prov.makeFile, ::prov.makeFileVal))
0285 {
0286 return false;
0287 }
0288 }
0289 }
0290 else
0291 {
0292 return false;
0293 }
0294
0295 return true;
0296 }
0297
0298 if (::install())
0299 {
0300 print("Go server gen ok!\n");
0301
0302 return 0;
0303 }
0304 else
0305 {
0306 print("Go server gen failed!\n");
0307 return -1;
0308 }