├── go
├── BSDmakefile
├── src
│ ├── restincl
│ │ ├── restin.ini
│ │ ├── README
│ │ ├── Makefile
│ │ ├── viewsupp.go
│ │ ├── fileupload.go
│ │ └── transactions.go
│ ├── exutil
│ │ ├── Makefile
│ │ ├── stopwatch.go
│ │ └── caroots.go
│ ├── tcpgatesv
│ │ ├── Makefile
│ │ ├── xatmipool.go
│ │ ├── outseq.go
│ │ ├── netin.go
│ │ ├── periodic.go
│ │ └── atmiout.go
│ ├── Makefile
│ ├── restoutsv
│ │ ├── Makefile
│ │ ├── periodic.go
│ │ ├── jsonerror.go
│ │ ├── xatmipool.go
│ │ └── viewsupp.go
│ └── ubftab
│ │ └── Makefile
└── Makefile
├── tests
├── 01_restin
│ ├── binary.test.response
│ ├── binary.test.request
│ ├── BSDmakefile
│ ├── runtime
│ │ ├── bin
│ │ │ ├── testsv
│ │ │ ├── trancl
│ │ │ ├── transv
│ │ │ └── restincl
│ │ ├── static
│ │ │ ├── other.txt
│ │ │ └── index.html
│ │ ├── ubftab
│ │ │ └── test.fd
│ │ ├── viewdir
│ │ │ └── restin.V
│ │ └── conf
│ │ │ ├── gencert.sh
│ │ │ └── ndrxconfig.xml
│ ├── src
│ │ ├── viewdir
│ │ │ ├── Makefile
│ │ │ └── restin.v_in
│ │ ├── Makefile
│ │ ├── trancl
│ │ │ └── Makefile
│ │ ├── transv
│ │ │ ├── Makefile
│ │ │ └── transv.go
│ │ ├── testsv
│ │ │ ├── Makefile
│ │ │ ├── textsv.go
│ │ │ ├── binary.go
│ │ │ ├── regexp.go
│ │ │ ├── cookies.go
│ │ │ ├── jsonsv.go
│ │ │ ├── fileupload.go
│ │ │ └── viewsv.go
│ │ └── ubftab
│ │ │ ├── Makefile
│ │ │ └── test.fd
│ └── Makefile
├── 02_tcpgatesv
│ ├── src
│ │ ├── exutil
│ │ ├── Makefile
│ │ ├── testcl
│ │ │ └── Makefile
│ │ ├── testsv
│ │ │ ├── Makefile
│ │ │ └── seqtest.go
│ │ └── ubftab
│ │ │ ├── Makefile
│ │ │ └── test.fd
│ ├── BSDmakefile
│ ├── runtime
│ │ ├── bin
│ │ │ ├── testcl
│ │ │ ├── testsv
│ │ │ └── tcpgatesv
│ │ ├── ubftab
│ │ │ └── test.fd
│ │ └── conf
│ │ │ ├── gencert.sh
│ │ │ └── ndrxconfig.xml
│ └── Makefile
├── 03_restout
│ ├── BSDmakefile
│ ├── runtime
│ │ ├── bin
│ │ │ ├── testcl
│ │ │ ├── bigmsgsv
│ │ │ ├── restincl
│ │ │ ├── testsv
│ │ │ └── restoutsv
│ │ ├── ubftab
│ │ │ └── test.fd
│ │ ├── viewdir
│ │ ├── conf
│ │ │ ├── debug.ini
│ │ │ ├── gencert.sh
│ │ │ ├── ndrxconfig.xml
│ │ │ ├── restin.ini
│ │ │ └── restout.ini
│ │ └── test.ud
│ ├── src
│ │ ├── viewdir
│ │ ├── Makefile
│ │ ├── testcl
│ │ │ ├── Makefile
│ │ │ └── testcl.go
│ │ ├── bigmsgsv
│ │ │ ├── Makefile
│ │ │ └── testsv.go
│ │ └── ubftab
│ │ │ ├── Makefile
│ │ │ └── test.fd
│ └── Makefile
├── Makefile
└── run.sh
├── doc
├── restinout_tutor_1.dia
├── restinout_tutor_1.png
├── pers_sync_net_to_ex.dia
├── pers_sync_net_to_ex.png
├── nonpers_sync_ex_to_net.dia
├── nonpers_sync_ex_to_net.png
├── nonpers_sync_net_to_ex.dia
├── nonpers_sync_net_to_ex.png
├── pers_async_net_to_ex_w_corr.dia
├── pers_async_net_to_ex_w_corr.png
├── pers_sync_ex_to_net_connid.dia
├── pers_sync_ex_to_net_connid.png
├── Makefile
├── pers_async_ex_to_net_wo_corr.dia
├── pers_async_ex_to_net_wo_corr.png
├── pers_async_net_to_ex_wo_corr.dia
├── pers_async_net_to_ex_wo_corr.png
├── manpage
│ └── Makefile
└── Mdoc
├── Makefile
├── .gitignore
├── pkg
├── README
└── CMakeLists.txt
└── README.md
/go/BSDmakefile:
--------------------------------------------------------------------------------
1 | all clean:
2 | gmake $@
3 |
--------------------------------------------------------------------------------
/tests/01_restin/binary.test.response:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/01_restin/binary.test.request:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/exutil:
--------------------------------------------------------------------------------
1 | ../../../go/src/exutil
--------------------------------------------------------------------------------
/tests/01_restin/BSDmakefile:
--------------------------------------------------------------------------------
1 | all clean:
2 | gmake $@
3 |
--------------------------------------------------------------------------------
/tests/01_restin/runtime/bin/testsv:
--------------------------------------------------------------------------------
1 | ../../src/testsv/testsv
--------------------------------------------------------------------------------
/tests/01_restin/runtime/bin/trancl:
--------------------------------------------------------------------------------
1 | ../../src/trancl/trancl
--------------------------------------------------------------------------------
/tests/01_restin/runtime/bin/transv:
--------------------------------------------------------------------------------
1 | ../../src/transv/transv
--------------------------------------------------------------------------------
/tests/03_restout/BSDmakefile:
--------------------------------------------------------------------------------
1 | all clean:
2 | gmake $@
3 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/bin/testcl:
--------------------------------------------------------------------------------
1 | ../../src/testcl/testcl
--------------------------------------------------------------------------------
/tests/03_restout/src/viewdir:
--------------------------------------------------------------------------------
1 | ../../01_restin/src/viewdir/
--------------------------------------------------------------------------------
/tests/01_restin/runtime/static/other.txt:
--------------------------------------------------------------------------------
1 | Some other file
2 |
--------------------------------------------------------------------------------
/tests/01_restin/runtime/ubftab/test.fd:
--------------------------------------------------------------------------------
1 | ../../src/ubftab/test.fd
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/BSDmakefile:
--------------------------------------------------------------------------------
1 | all clean:
2 | gmake $@
3 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/runtime/bin/testcl:
--------------------------------------------------------------------------------
1 | ../../src/testcl/testcl
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/runtime/bin/testsv:
--------------------------------------------------------------------------------
1 | ../../src/testsv/testsv
--------------------------------------------------------------------------------
/tests/03_restout/runtime/ubftab/test.fd:
--------------------------------------------------------------------------------
1 | ../../src/ubftab/test.fd
--------------------------------------------------------------------------------
/tests/03_restout/runtime/viewdir:
--------------------------------------------------------------------------------
1 | ../../01_restin/src/viewdir
--------------------------------------------------------------------------------
/tests/01_restin/runtime/viewdir/restin.V:
--------------------------------------------------------------------------------
1 | ../../src/viewdir/restin.V
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/runtime/ubftab/test.fd:
--------------------------------------------------------------------------------
1 | ../../src/ubftab/test.fd
--------------------------------------------------------------------------------
/tests/03_restout/runtime/bin/bigmsgsv:
--------------------------------------------------------------------------------
1 | ../../src/bigmsgsv/bigmsgsv
--------------------------------------------------------------------------------
/tests/01_restin/runtime/bin/restincl:
--------------------------------------------------------------------------------
1 | ../../../../go/src/restincl/restincl
--------------------------------------------------------------------------------
/tests/03_restout/runtime/bin/restincl:
--------------------------------------------------------------------------------
1 | ../../../../go/src/restincl/restincl
--------------------------------------------------------------------------------
/tests/03_restout/runtime/bin/testsv:
--------------------------------------------------------------------------------
1 | ../../../01_restin/src/testsv/testsv
--------------------------------------------------------------------------------
/go/src/restincl/restin.ini:
--------------------------------------------------------------------------------
1 | ../../../tests/01_restin/runtime/conf/restin.ini
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/runtime/bin/tcpgatesv:
--------------------------------------------------------------------------------
1 | ../../../../go/src/tcpgatesv/tcpgatesv
--------------------------------------------------------------------------------
/tests/03_restout/runtime/bin/restoutsv:
--------------------------------------------------------------------------------
1 | ../../../../go/src/restoutsv/restoutsv
--------------------------------------------------------------------------------
/doc/restinout_tutor_1.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/restinout_tutor_1.dia
--------------------------------------------------------------------------------
/doc/restinout_tutor_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/restinout_tutor_1.png
--------------------------------------------------------------------------------
/doc/pers_sync_net_to_ex.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_sync_net_to_ex.dia
--------------------------------------------------------------------------------
/doc/pers_sync_net_to_ex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_sync_net_to_ex.png
--------------------------------------------------------------------------------
/doc/nonpers_sync_ex_to_net.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/nonpers_sync_ex_to_net.dia
--------------------------------------------------------------------------------
/doc/nonpers_sync_ex_to_net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/nonpers_sync_ex_to_net.png
--------------------------------------------------------------------------------
/doc/nonpers_sync_net_to_ex.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/nonpers_sync_net_to_ex.dia
--------------------------------------------------------------------------------
/doc/nonpers_sync_net_to_ex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/nonpers_sync_net_to_ex.png
--------------------------------------------------------------------------------
/tests/01_restin/runtime/static/index.html:
--------------------------------------------------------------------------------
1 |
Hello world
2 |
--------------------------------------------------------------------------------
/doc/pers_async_net_to_ex_w_corr.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_async_net_to_ex_w_corr.dia
--------------------------------------------------------------------------------
/doc/pers_async_net_to_ex_w_corr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_async_net_to_ex_w_corr.png
--------------------------------------------------------------------------------
/doc/pers_sync_ex_to_net_connid.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_sync_ex_to_net_connid.dia
--------------------------------------------------------------------------------
/doc/pers_sync_ex_to_net_connid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_sync_ex_to_net_connid.png
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | $(MAKE) -f Mdoc
3 | $(MAKE) -C manpage
4 | clean:
5 | $(MAKE) -f Mdoc clean
6 | $(MAKE) -C manpage clean
7 |
--------------------------------------------------------------------------------
/doc/pers_async_ex_to_net_wo_corr.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_async_ex_to_net_wo_corr.dia
--------------------------------------------------------------------------------
/doc/pers_async_ex_to_net_wo_corr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_async_ex_to_net_wo_corr.png
--------------------------------------------------------------------------------
/doc/pers_async_net_to_ex_wo_corr.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_async_net_to_ex_wo_corr.dia
--------------------------------------------------------------------------------
/doc/pers_async_net_to_ex_wo_corr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endurox-dev/endurox-connect/HEAD/doc/pers_async_net_to_ex_wo_corr.png
--------------------------------------------------------------------------------
/go/src/restincl/README:
--------------------------------------------------------------------------------
1 | Create an atmi client, read from socket, pipe done via channel to pool.
2 | For config use NDRX_CCTAG env as sub-section.
3 |
--------------------------------------------------------------------------------
/go/Makefile:
--------------------------------------------------------------------------------
1 | export GOPATH=$(shell pwd)
2 | export GO111MODULE=auto
3 |
4 | all:
5 | $(MAKE) -C src
6 |
7 | clean:
8 | rm -rf pkg bin
9 | $(MAKE) -C src clean
10 |
11 |
12 | .PHONY: clean all
13 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/conf/debug.ini:
--------------------------------------------------------------------------------
1 | [@debug]
2 | testcl= ndrx=3 ubf=1 tp=3 file=${NDRX_APPHOME}/log/testcl.log threaded=y
3 | testsv= ndrx=3 ubf=1 tp=3 file=${NDRX_APPHOME}/log/testsv.log threaded=y
4 |
5 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/test.ud:
--------------------------------------------------------------------------------
1 | SRVCNM JUERRORS
2 | T_CHAR_FLD A
3 | T_SHORT_FLD 123
4 | T_LONG_FLD 444444444
5 | T_FLOAT_FLD 1.33
6 | T_DOUBLE_FLD 4444.3333
7 | T_STRING_FLD HELLO
8 | T_CARRAY_FLD WORLD
9 |
10 |
--------------------------------------------------------------------------------
/tests/01_restin/src/viewdir/Makefile:
--------------------------------------------------------------------------------
1 |
2 | unexport VIEWDIR
3 | unexport VIEWFILES
4 |
5 | .DEFAULT_GOAL := restin.V
6 |
7 | restin.V: restin.v_in
8 | viewc -n restin.v_in
9 |
10 |
11 | clean:
12 | -rm *.V
13 |
--------------------------------------------------------------------------------
/tests/01_restin/Makefile:
--------------------------------------------------------------------------------
1 | export GOPATH=$(shell pwd)
2 | export GO111MODULE=auto
3 |
4 | all:
5 | $(MAKE) -C src
6 |
7 | clean:
8 | rm -rf pkg bin
9 | $(MAKE) -C src clean
10 |
11 |
12 |
13 | .PHONY: clean all
14 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/Makefile:
--------------------------------------------------------------------------------
1 | export GOPATH=$(shell pwd)
2 | export GO111MODULE=auto
3 |
4 | all:
5 | $(MAKE) -C src
6 |
7 | clean:
8 | rm -rf pkg bin
9 | $(MAKE) -C src clean
10 |
11 |
12 |
13 | .PHONY: clean all
14 |
--------------------------------------------------------------------------------
/tests/03_restout/Makefile:
--------------------------------------------------------------------------------
1 | export GOPATH=$(shell pwd)
2 | export GO111MODULE=auto
3 |
4 | all:
5 | $(MAKE) -C src
6 |
7 | clean:
8 | rm -rf pkg bin
9 | $(MAKE) -C src clean
10 |
11 |
12 |
13 | .PHONY: clean all
14 |
--------------------------------------------------------------------------------
/tests/Makefile:
--------------------------------------------------------------------------------
1 | # Do recursive builds
2 | all:
3 | $(MAKE) -C 01_restin
4 | $(MAKE) -C 02_tcpgatesv
5 | $(MAKE) -C 03_restout
6 |
7 | clean:
8 | $(MAKE) -C 01_restin clean
9 | $(MAKE) -C 02_tcpgatesv clean
10 | $(MAKE) -C 03_restout clean
11 |
12 | .PHONY: clean all
13 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 |
3 | .PHONY: all pkg clean doc
4 |
5 |
6 | # Do recursive builds
7 | all:
8 | $(MAKE) -C go
9 | $(MAKE) -C tests
10 | cd pkg && cmake .
11 |
12 | clean:
13 | $(MAKE) -C tests clean
14 | $(MAKE) -C go clean
15 |
16 | doc:
17 | $(MAKE) -C doc
18 |
19 | pkg: all
20 | cd pkg && cpack
21 |
22 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/Makefile:
--------------------------------------------------------------------------------
1 | # Do recursive builds
2 | all:
3 | go get -u github.com/endurox-dev/endurox-go && cd github.com/endurox-dev/endurox-go && git checkout v8.0
4 | $(MAKE) -C ubftab
5 | $(MAKE) -C testsv
6 | $(MAKE) -C testcl
7 |
8 | clean:
9 | $(MAKE) -C ubftab clean
10 | $(MAKE) -C testsv clean
11 | $(MAKE) -C testcl clean
12 |
13 | .PHONY: clean all
14 |
--------------------------------------------------------------------------------
/tests/03_restout/src/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | go get -u github.com/endurox-dev/endurox-go && cd github.com/endurox-dev/endurox-go && git checkout v8.0
3 | $(MAKE) -C ubftab
4 | $(MAKE) -C testcl
5 | $(MAKE) -C viewdir
6 | $(MAKE) -C bigmsgsv
7 |
8 | clean:
9 | $(MAKE) -C ubftab clean
10 | $(MAKE) -C testcl clean
11 | $(MAKE) -C viewdir clean
12 | $(MAKE) -C bigmsgsv clean
13 |
14 |
15 | .PHONY: clean all
16 |
17 |
--------------------------------------------------------------------------------
/go/src/exutil/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
4 |
5 | LIBRARY=exutil
6 | LDFLAGS=
7 |
8 | VERSION=1.0.0
9 | BUILD_TIME=`date +%FT%T%z`
10 |
11 | .DEFAULT_GOAL: $(LIBRARY)
12 |
13 | $(LIBRARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${LIBRARY} *.go
15 | go install ${LDFLAGS} ./...
16 |
17 | .PHONY: clean
18 | clean:
19 | if [ -f ${LIBRARY} ] ; then rm ${LIBRARY} ; fi
20 |
21 |
--------------------------------------------------------------------------------
/tests/01_restin/src/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | go get -u github.com/endurox-dev/endurox-go && cd github.com/endurox-dev/endurox-go && git checkout v8.0
3 | $(MAKE) -C ubftab
4 | $(MAKE) -C testsv
5 | $(MAKE) -C transv
6 | $(MAKE) -C trancl
7 | $(MAKE) -C viewdir
8 |
9 | clean:
10 | $(MAKE) -C ubftab clean
11 | $(MAKE) -C testsv clean
12 | $(MAKE) -C transv clean
13 | $(MAKE) -C trancl clean
14 | $(MAKE) -C viewdir clean
15 |
16 |
17 | .PHONY: clean all
18 |
--------------------------------------------------------------------------------
/go/src/tcpgatesv/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
4 |
5 | BINARY=tcpgatesv
6 | LDFLAGS=
7 |
8 | VERSION=1.0.0
9 | BUILD_TIME=`date +%FT%T%z`
10 |
11 | .DEFAULT_GOAL: $(BINARY)
12 |
13 | $(BINARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${BINARY} *.go
15 |
16 | .PHONY: install
17 | install:
18 | go install ${LDFLAGS} ./...
19 |
20 | .PHONY: clean
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/tests/01_restin/src/trancl/Makefile:
--------------------------------------------------------------------------------
1 | SOURCEDIR=.
2 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
3 |
4 | BINARY=trancl
5 | LDFLAGS=
6 |
7 | VERSION=1.0.0
8 | BUILD_TIME=`date +%FT%T%z`
9 |
10 | .DEFAULT_GOAL: $(BINARY)
11 |
12 | $(BINARY): $(SOURCES)
13 | go build ${LDFLAGS} -o ${BINARY} *.go
14 |
15 | .PHONY: install
16 | install:
17 | go install ${LDFLAGS} ./...
18 |
19 | .PHONY: clean
20 | clean:
21 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
22 |
--------------------------------------------------------------------------------
/tests/01_restin/src/transv/Makefile:
--------------------------------------------------------------------------------
1 | SOURCEDIR=.
2 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
3 |
4 | BINARY=transv
5 | LDFLAGS=
6 |
7 | VERSION=1.0.0
8 | BUILD_TIME=`date +%FT%T%z`
9 |
10 | .DEFAULT_GOAL: $(BINARY)
11 |
12 | $(BINARY): $(SOURCES)
13 | go build ${LDFLAGS} -o ${BINARY} *.go
14 |
15 | .PHONY: install
16 | install:
17 | go install ${LDFLAGS} ./...
18 |
19 | .PHONY: clean
20 | clean:
21 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
22 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
4 |
5 | BINARY=testsv
6 | LDFLAGS=
7 |
8 | VERSION=1.0.0
9 | BUILD_TIME=`date +%FT%T%z`
10 |
11 | .DEFAULT_GOAL: $(BINARY)
12 |
13 | $(BINARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${BINARY} *.go
15 |
16 | .PHONY: install
17 | install:
18 | go install ${LDFLAGS} ./...
19 |
20 | .PHONY: clean
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/tests/03_restout/src/testcl/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
4 |
5 | BINARY=testcl
6 | LDFLAGS=
7 |
8 | VERSION=1.0.0
9 | BUILD_TIME=`date +%FT%T%z`
10 |
11 | .DEFAULT_GOAL: $(BINARY)
12 |
13 | $(BINARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${BINARY} *.go
15 |
16 | .PHONY: install
17 | install:
18 | go install ${LDFLAGS} ./...
19 |
20 | .PHONY: clean
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/testcl/Makefile:
--------------------------------------------------------------------------------
1 | SOURCEDIR=.
2 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
3 |
4 | BINARY=testcl
5 | LDFLAGS=
6 |
7 | VERSION=1.0.0
8 | BUILD_TIME=`date +%FT%T%z`
9 |
10 | .DEFAULT_GOAL: $(BINARY)
11 |
12 | $(BINARY): $(SOURCES)
13 | go build ${LDFLAGS} -o ${BINARY} *.go
14 |
15 | .PHONY: install
16 | install:
17 | go install ${LDFLAGS} ./...
18 |
19 | .PHONY: clean
20 |
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/tests/03_restout/src/bigmsgsv/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
4 |
5 | BINARY=bigmsgsv
6 | LDFLAGS=
7 |
8 | VERSION=1.0.0
9 | BUILD_TIME=`date +%FT%T%z`
10 |
11 | .DEFAULT_GOAL: $(BINARY)
12 |
13 | $(BINARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${BINARY} *.go
15 |
16 | .PHONY: install
17 | install:
18 | go install ${LDFLAGS} ./...
19 |
20 | .PHONY: clean
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/testsv/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
4 |
5 | BINARY=testsv
6 | #LDFLAGS=-race
7 | LDFLAGS=
8 |
9 | VERSION=1.0.0
10 | BUILD_TIME=`date +%FT%T%z`
11 |
12 | .DEFAULT_GOAL: $(BINARY)
13 |
14 | $(BINARY): $(SOURCES)
15 | go build ${LDFLAGS} -o ${BINARY} *.go
16 |
17 | .PHONY: install
18 | install:
19 | go install ${LDFLAGS} ./...
20 |
21 | .PHONY: clean
22 | clean:
23 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
24 |
--------------------------------------------------------------------------------
/go/src/Makefile:
--------------------------------------------------------------------------------
1 | # Do recursive builds
2 | all:
3 | go get -u github.com/endurox-dev/endurox-go && cd github.com/endurox-dev/endurox-go && git checkout v8.0
4 | $(MAKE) -C ubftab
5 | $(MAKE) -C exutil
6 | $(MAKE) -C restincl
7 | $(MAKE) -C restoutsv
8 | $(MAKE) -C tcpgatesv
9 |
10 | clean:
11 | - rm -rf github.com/endurox-dev
12 | $(MAKE) -C ubftab clean
13 | $(MAKE) -C exutil clean
14 | $(MAKE) -C restincl clean
15 | $(MAKE) -C restoutsv clean
16 | $(MAKE) -C tcpgatesv clean
17 |
18 | .PHONY: clean
19 |
--------------------------------------------------------------------------------
/go/src/restincl/Makefile:
--------------------------------------------------------------------------------
1 | SOURCEDIR=.
2 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
3 |
4 | BINARY=restincl
5 |
6 | VERSION=1.0.0
7 | BUILD_TIME=`date +%FT%T%z`
8 |
9 | #LDFLAGS=-ldflags "-X github.com/ariejan/roll/core.Version=${VERSION} -X github.com/ariejan/roll/core.BuildTime=${BUILD_TIME}"
10 |
11 | .DEFAULT_GOAL: $(BINARY)
12 |
13 | $(BINARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${BINARY} *.go
15 |
16 | .PHONY: install
17 | install:
18 | go install ${LDFLAGS} ./...
19 |
20 | .PHONY: clean
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/go/src/restoutsv/Makefile:
--------------------------------------------------------------------------------
1 | SOURCEDIR=.
2 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
3 |
4 | BINARY=restoutsv
5 |
6 | VERSION=1.0.0
7 | BUILD_TIME=`date +%FT%T%z`
8 |
9 | #LDFLAGS=-ldflags "-X github.com/ariejan/roll/core.Version=${VERSION} -X github.com/ariejan/roll/core.BuildTime=${BUILD_TIME}"
10 |
11 | .DEFAULT_GOAL: $(BINARY)
12 |
13 | $(BINARY): $(SOURCES)
14 | go build ${LDFLAGS} -o ${BINARY} *.go
15 |
16 | .PHONY: install
17 | install:
18 | go install ${LDFLAGS} ./...
19 |
20 | .PHONY: clean
21 | clean:
22 | if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
23 |
--------------------------------------------------------------------------------
/go/src/ubftab/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.fd')
4 | SOURCES += Exfields
5 |
6 | OUTPUT = $(addsuffix .go, $(SOURCES))
7 |
8 | comma:= ,
9 | empty:=
10 | space:= $(empty) $(empty)
11 |
12 | export FIELDTBLS=$(subst $(space),$(comma),$(SOURCES))
13 | export FLDTBLDIR=$(shell pwd)
14 |
15 | $(info $$SOURCES is [${SOURCES}])
16 | $(info $$OUTPUT is [${OUTPUT}])
17 | $(info $$FIELDTBLS is [${FIELDTBLS}])
18 |
19 | PACKAGE=ubftab
20 |
21 | .DEFAULT_GOAL: $(OUTPUT)
22 | LDFLAGS=
23 |
24 | $(OUTPUT): $(SOURCES)
25 | mkfldhdr -m1 -p${PACKAGE}
26 | go build ${LDFLAGS} -o ${PACKAGE} *.go
27 | go install ${LDFLAGS} ./...
28 |
29 | .PHONY: clean
30 | clean:
31 | - rm *.go ${PACKAGE}
32 |
--------------------------------------------------------------------------------
/tests/01_restin/src/ubftab/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.fd')
4 | SOURCES += Exfields
5 |
6 | OUTPUT = $(addsuffix .go, $(SOURCES))
7 |
8 | comma:= ,
9 | empty:=
10 | space:= $(empty) $(empty)
11 |
12 | export FIELDTBLS=$(subst $(space),$(comma),$(SOURCES))
13 | export FLDTBLDIR=$(shell pwd)
14 |
15 | $(info $$SOURCES is [${SOURCES}])
16 | $(info $$OUTPUT is [${OUTPUT}])
17 | $(info $$FIELDTBLS is [${FIELDTBLS}])
18 |
19 | PACKAGE=ubftab
20 |
21 | .DEFAULT_GOAL: $(OUTPUT)
22 | LDFLAGS=
23 |
24 | $(OUTPUT): $(SOURCES)
25 | mkfldhdr -m1 -p${PACKAGE}
26 | go build ${LDFLAGS} -o ${PACKAGE} *.go
27 | go install ${LDFLAGS} ./...
28 |
29 | .PHONY: clean
30 | clean:
31 | - rm *.go
32 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/ubftab/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.fd')
4 | SOURCES += Exfields
5 |
6 | OUTPUT = $(addsuffix .go, $(SOURCES))
7 |
8 | comma:= ,
9 | empty:=
10 | space:= $(empty) $(empty)
11 |
12 | export FIELDTBLS=$(subst $(space),$(comma),$(SOURCES))
13 | export FLDTBLDIR=$(shell pwd)
14 |
15 | $(info $$SOURCES is [${SOURCES}])
16 | $(info $$OUTPUT is [${OUTPUT}])
17 | $(info $$FIELDTBLS is [${FIELDTBLS}])
18 |
19 | PACKAGE=ubftab
20 |
21 | .DEFAULT_GOAL: $(OUTPUT)
22 | LDFLAGS=
23 |
24 | $(OUTPUT): $(SOURCES)
25 | mkfldhdr -m1 -p${PACKAGE}
26 | go build ${LDFLAGS} -o ${PACKAGE} *.go
27 | go install ${LDFLAGS} ./...
28 |
29 | .PHONY: clean
30 | clean:
31 | - rm *.go
32 |
--------------------------------------------------------------------------------
/tests/03_restout/src/ubftab/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SOURCEDIR=.
3 | SOURCES := $(shell find $(SOURCEDIR) -name '*.fd')
4 | SOURCES += Exfields
5 |
6 | OUTPUT = $(addsuffix .go, $(SOURCES))
7 |
8 | comma:= ,
9 | empty:=
10 | space:= $(empty) $(empty)
11 |
12 | export FIELDTBLS=$(subst $(space),$(comma),$(SOURCES))
13 | export FLDTBLDIR=$(shell pwd)
14 |
15 | $(info $$SOURCES is [${SOURCES}])
16 | $(info $$OUTPUT is [${OUTPUT}])
17 | $(info $$FIELDTBLS is [${FIELDTBLS}])
18 |
19 | PACKAGE=ubftab
20 |
21 | .DEFAULT_GOAL: $(OUTPUT)
22 | LDFLAGS=
23 |
24 | $(OUTPUT): $(SOURCES)
25 | mkfldhdr -m1 -p${PACKAGE}
26 | go build ${LDFLAGS} -o ${PACKAGE} *.go
27 | go install ${LDFLAGS} ./...
28 |
29 | .PHONY: clean
30 | clean:
31 | - rm *.go
32 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/textsv.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import atmi "github.com/endurox-dev/endurox-go"
4 |
5 | //Text service
6 | //@param ac ATMI Context
7 | //@param svc Service call information
8 | func TEXTSV(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
9 |
10 | ret := SUCCEED
11 |
12 | //Get UBF Handler
13 | sb, _ := ac.CastToString(&svc.Data)
14 |
15 | //Return to the caller
16 | defer func() {
17 | if SUCCEED == ret {
18 | ac.TpReturn(atmi.TPSUCCESS, 0, sb, 0)
19 | } else {
20 | ac.TpReturn(atmi.TPFAIL, 0, sb, 0)
21 | }
22 | }()
23 |
24 | ac.TpLogWarn("Got string request...")
25 |
26 | ac.TpLogInfo("Got text: [%s]", sb.GetString())
27 |
28 | sb.SetString("Hello from EnduroX")
29 |
30 | return
31 | }
32 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/binary.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | atmi "github.com/endurox-dev/endurox-go"
5 | )
6 |
7 | //Binary service
8 | //@param ac ATMI Context
9 | //@param svc Service call information
10 | func BINARYSV(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
11 |
12 | ret := SUCCEED
13 |
14 | //Get UBF Handler
15 | bb, _ := ac.CastToCarray(&svc.Data)
16 |
17 | //Return to the caller
18 | defer func() {
19 | if SUCCEED == ret {
20 | ac.TpReturn(atmi.TPSUCCESS, 0, bb, 0)
21 | } else {
22 | ac.TpReturn(atmi.TPFAIL, 0, bb, 0)
23 | }
24 | }()
25 |
26 | bb.GetBytes()
27 | ac.TpLogDump(atmi.LOG_INFO, "Got binary request buffer",
28 | bb.GetBytes(), len(bb.GetBytes()))
29 |
30 | bb.SetBytes([]byte{9,8,7,6,5,4,3,2,1,0})
31 |
32 | ac.TpLogDump(atmi.LOG_INFO, "Responding with buffer", bb.GetBytes(),
33 | len(bb.GetBytes()))
34 |
35 | return
36 | }
37 |
--------------------------------------------------------------------------------
/tests/01_restin/src/viewdir/restin.v_in:
--------------------------------------------------------------------------------
1 | VIEW REQUEST1
2 | #type cname fbname count flag size null
3 |
4 | short tshort1 - 1 - - -
5 | long tlong1 - 1 - - -
6 | string tstring1 - 3 - 18 -
7 |
8 | # Response
9 | int rspcode - 1 - - -
10 | string rspmessage - 1 - 255 -
11 |
12 | END
13 |
14 | #
15 | # This do not have resposne fields inside
16 | #
17 | VIEW REQUEST2
18 | #type cname fbname count flag size null
19 |
20 | short tshort2 - 1 - - -
21 | long tlong2 - 1 - - -
22 | string tstring2 - 1 - 20 -
23 |
24 | END
25 |
26 | #
27 | # Pure resposne object, and short response message field to test trucate
28 | #
29 | VIEW RSPV
30 | #type cname fbname count flag size null
31 | int rspcode - 1 - - -
32 | string rspmessage - 1 - 4 -
33 | END
34 |
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | go/pkg/
2 | go/src/exutil/exutil
3 | go/src/github.com/
4 | go/src/restincl/restincl
5 | go/src/restoutsv/restoutsv
6 | go/src/tcpgatesv/tcpgatesv
7 | go/src/ubftab/Exfields.go
8 | go/src/ubftab/ubftab
9 | pkg/CMakeCache.txt
10 | pkg/CMakeFiles/
11 | pkg/CPackConfig.cmake
12 | pkg/CPackSourceConfig.cmake
13 | pkg/Makefile
14 | pkg/cmake_install.cmake
15 | tests/01_restin/pkg/
16 | tests/01_restin/src/github.com/
17 | tests/01_restin/src/testsv/testsv
18 | tests/01_restin/src/ubftab/Exfields.go
19 | tests/01_restin/src/ubftab/test.fd.go
20 | tests/01_restin/src/ubftab/ubftab
21 | tests/02_tcpgatesv/pkg/
22 | tests/02_tcpgatesv/src/github.com/
23 | tests/02_tcpgatesv/src/testcl/testcl
24 | tests/02_tcpgatesv/src/testsv/testsv
25 | tests/02_tcpgatesv/src/ubftab/Exfields.go
26 | tests/02_tcpgatesv/src/ubftab/test.fd.go
27 | tests/02_tcpgatesv/src/ubftab/ubftab
28 | tests/03_restout/pkg/
29 | tests/03_restout/src/github.com/
30 | tests/03_restout/src/testcl/testcl
31 | tests/03_restout/src/ubftab/Exfields.go
32 | tests/03_restout/src/ubftab/test.fd.go
33 | tests/03_restout/src/ubftab/ubftab
34 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/regexp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import atmi "github.com/endurox-dev/endurox-go"
4 |
5 | //Regexp UBF service
6 | //@param ac ATMI Context
7 | //@param svc Service call information
8 | func REGEXP(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
9 |
10 | ret := SUCCEED
11 |
12 | //Get UBF Handler
13 | ub, _ := ac.CastToUBF(&svc.Data)
14 |
15 | //Return to the caller
16 | defer func() {
17 | if SUCCEED == ret {
18 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
19 | } else {
20 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
21 | }
22 | }()
23 |
24 | ac.TpLogInfo("Got UBF: [%v]", ub)
25 |
26 | return
27 | }
28 |
29 | //Regexp JSON service
30 | //@param ac ATMI Context
31 | //@param svc Service call information
32 | func REGEXPJSON(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
33 |
34 | ret := SUCCEED
35 |
36 | //Get UBF Handler
37 | jb, _ := ac.CastToJSON(&svc.Data)
38 |
39 | //Return to the caller
40 | defer func() {
41 | if SUCCEED == ret {
42 | ac.TpReturn(atmi.TPSUCCESS, 0, jb, 0)
43 | } else {
44 | ac.TpReturn(atmi.TPFAIL, 0, jb, 0)
45 | }
46 | }()
47 |
48 | ac.TpLogInfo("Got json: [%v]", jb)
49 |
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/runtime/conf/gencert.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Generate test CA, Client cert, Server Cert
5 | #
6 |
7 | TEST_HOSTNAME=`hostname`
8 | echo "Host name is [$TEST_HOSTNAME]"
9 |
10 | set -x
11 |
12 | echo "subjectAltName=DNS:$TEST_HOSTNAME" > altsubj.ext
13 |
14 | # Generate root CA
15 | openssl req -nodes -x509 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/C=LV/ST=RIGA/L=Riga/O=Endurox_CA/OU=root/CN=$TEST_HOSTNAME/emailAddress=test@mavimax.com"
16 |
17 | # Generate server cert
18 | openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=LV/ST=RIGA/L=Riga/O=Endurox_SV/OU=root/CN=$TEST_HOSTNAME/emailAddress=test@mavimax.com"
19 |
20 | # Sign server cert
21 | openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile altsubj.ext
22 |
23 | # Generate client cert
24 | openssl req -nodes -newkey rsa:2048 -keyout client.key -out client.csr -subj "/C=LV/ST=RIGA/L=Riga/O=Endurox_CL/OU=root/CN=$TEST_HOSTNAME/emailAddress=test@mavimax.com"
25 |
26 | # Sign client cert
27 | openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out client.crt -extfile altsubj.ext
28 |
29 |
--------------------------------------------------------------------------------
/tests/01_restin/src/ubftab/test.fd:
--------------------------------------------------------------------------------
1 |
2 | $#ifndef __TEST_FD
3 | $#define __TEST_FD
4 |
5 | *base 6000
6 |
7 |
8 | T_CHAR_FLD 11 char - 1 Chart test field 1
9 | T_CHAR_2_FLD 12 char - 1 Chart test field 2
10 | T_SHORT_FLD 21 short - 1 Short test field 1
11 | T_SHORT_2_FLD 22 short - 1 Short test field 2
12 | T_LONG_FLD 31 long - 1 Long test field 1
13 | T_LONG_2_FLD 32 long - 1 Long test field 2
14 | T_FLOAT_FLD 41 float - 1 Float test field 1
15 | T_FLOAT_2_FLD 42 float - 1 Float test field 2
16 | T_FLOAT_3_FLD 43 float - 1 Float test field 3
17 | T_DOUBLE_FLD 51 double - 1 Double test field 1
18 | T_DOUBLE_2_FLD 52 double - 1 Double test field 2
19 | T_DOUBLE_3_FLD 53 double - 1 Double test field 3
20 | T_DOUBLE_4_FLD 54 double - 1 Double test field 4
21 | T_STRING_FLD 61 string - 1 String test field 1
22 | T_STRING_2_FLD 62 string - 1 String test field 2
23 | T_STRING_3_FLD 63 string - 1 String test field 3
24 | T_STRING_4_FLD 64 string - 1 String test field 4
25 | T_STRING_5_FLD 65 string - 1 String test field 5
26 | T_STRING_6_FLD 66 string - 1 String test field 6
27 | T_STRING_7_FLD 67 string - 1 String test field 7
28 | T_STRING_8_FLD 68 string - 1 String test field 8
29 | T_STRING_9_FLD 69 string - 1 String test field 9
30 | T_STRING_10_FLD 10 string - 1 String test field 10
31 | T_CARRAY_FLD 81 carray - 1 Carray test field 1
32 | T_CARRAY_2_FLD 82 carray - 1 Carray test field 2
33 |
34 |
35 | $#endif
36 |
--------------------------------------------------------------------------------
/tests/03_restout/src/ubftab/test.fd:
--------------------------------------------------------------------------------
1 |
2 | $#ifndef __TEST_FD
3 | $#define __TEST_FD
4 |
5 | *base 6000
6 |
7 |
8 | T_CHAR_FLD 11 char - 1 Chart test field 1
9 | T_CHAR_2_FLD 12 char - 1 Chart test field 2
10 | T_SHORT_FLD 21 short - 1 Short test field 1
11 | T_SHORT_2_FLD 22 short - 1 Short test field 2
12 | T_LONG_FLD 31 long - 1 Long test field 1
13 | T_LONG_2_FLD 32 long - 1 Long test field 2
14 | T_FLOAT_FLD 41 float - 1 Float test field 1
15 | T_FLOAT_2_FLD 42 float - 1 Float test field 2
16 | T_FLOAT_3_FLD 43 float - 1 Float test field 3
17 | T_DOUBLE_FLD 51 double - 1 Double test field 1
18 | T_DOUBLE_2_FLD 52 double - 1 Double test field 2
19 | T_DOUBLE_3_FLD 53 double - 1 Double test field 3
20 | T_DOUBLE_4_FLD 54 double - 1 Double test field 4
21 | T_STRING_FLD 61 string - 1 String test field 1
22 | T_STRING_2_FLD 62 string - 1 String test field 2
23 | T_STRING_3_FLD 63 string - 1 String test field 3
24 | T_STRING_4_FLD 64 string - 1 String test field 4
25 | T_STRING_5_FLD 65 string - 1 String test field 5
26 | T_STRING_6_FLD 66 string - 1 String test field 6
27 | T_STRING_7_FLD 67 string - 1 String test field 7
28 | T_STRING_8_FLD 68 string - 1 String test field 8
29 | T_STRING_9_FLD 69 string - 1 String test field 9
30 | T_STRING_10_FLD 10 string - 1 String test field 10
31 | T_CARRAY_FLD 81 carray - 1 Carray test field 1
32 | T_CARRAY_2_FLD 82 carray - 1 Carray test field 2
33 |
34 |
35 | $#endif
36 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/ubftab/test.fd:
--------------------------------------------------------------------------------
1 |
2 | $#ifndef __TEST_FD
3 | $#define __TEST_FD
4 |
5 | *base 6000
6 |
7 |
8 | T_CHAR_FLD 11 char - 1 Chart test field 1
9 | T_CHAR_2_FLD 12 char - 1 Chart test field 2
10 | T_SHORT_FLD 21 short - 1 Short test field 1
11 | T_SHORT_2_FLD 22 short - 1 Short test field 2
12 | T_LONG_FLD 31 long - 1 Long test field 1
13 | T_LONG_2_FLD 32 long - 1 Long test field 2
14 | T_FLOAT_FLD 41 float - 1 Float test field 1
15 | T_FLOAT_2_FLD 42 float - 1 Float test field 2
16 | T_FLOAT_3_FLD 43 float - 1 Float test field 3
17 | T_DOUBLE_FLD 51 double - 1 Double test field 1
18 | T_DOUBLE_2_FLD 52 double - 1 Double test field 2
19 | T_DOUBLE_3_FLD 53 double - 1 Double test field 3
20 | T_DOUBLE_4_FLD 54 double - 1 Double test field 4
21 | T_STRING_FLD 61 string - 1 String test field 1
22 | T_STRING_2_FLD 62 string - 1 String test field 2
23 | T_STRING_3_FLD 63 string - 1 String test field 3
24 | T_STRING_4_FLD 64 string - 1 String test field 4
25 | T_STRING_5_FLD 65 string - 1 String test field 5
26 | T_STRING_6_FLD 66 string - 1 String test field 6
27 | T_STRING_7_FLD 67 string - 1 String test field 7
28 | T_STRING_8_FLD 68 string - 1 String test field 8
29 | T_STRING_9_FLD 69 string - 1 String test field 9
30 | T_STRING_10_FLD 10 string - 1 String test field 10
31 | T_CARRAY_FLD 81 carray - 1 Carray test field 1
32 | T_CARRAY_2_FLD 82 carray - 1 Carray test field 2
33 |
34 |
35 | $#endif
36 |
--------------------------------------------------------------------------------
/pkg/README:
--------------------------------------------------------------------------------
1 | Using cmake as pacakge generator
2 |
3 | Releases:
4 |
5 |
6 | 2.0.0 - Completed restin/restout/tcpgate
7 | 2.1.2 - Fixes of Bug #200, Bug #201
8 | 2.1.3 - Feature #204
9 | 2.1.4 - View support in restincl
10 | 2.2.1 - (development version) Bug #225, works on restout view support
11 | 2.2.2 - (stable version) Bug #227
12 | 2.3.0 - Support for big message size
13 | 2.4.0 - Support for message length offset and keep header - Feature #273
14 | 2.4.2 - Feature #278 - provide compiled connection id to status service
15 | 2.4.3 - Feature #289 - print in log file caller ip address from which restin got call
16 | 2.4.5 - Works on Bug #285 (in progress)
17 | 2.4.6 - Finished Bug #285
18 | 2.4.8 - Fixed #305
19 | 2.4.10 - Implemented Feature #340
20 | 2.4.12 - Fixed Bug #356
21 | 2.4.14 - Implemented Feature #384 - static content serving
22 | 2.4.16 - Feature #377 - ext mode (in/out filters)
23 | 2.4.18 - Bug #461
24 | 2.4.20 - Updates on ext mode processing now body is loaded into EX_IF_REQDATA/EX_IF_RSPDATA fields
25 | 2.4.22 - Feature #509 - added EX_IF_METHOD for ext (web method post/get, etc..)
26 | 2.4.24 - Feature #531 - Optmizations (linger flag, less data array compies, quicker copies)
27 | 2.4.26 - Feature #596 - tls support in tcpgatesv
28 | 2.4.28 - Bug #607 - tcpgatesv if invalid tls_ca_roots is given, no error is returned
29 | 2.4.30 - Feature #606 - file upload
30 | 2.5.0 - Feature #640 - transactions API
31 | 8.0.0 - Building against endurox-go@v8.0, Support #754, Bug #757
32 | 8.0.2 - Bug #770, Support #780
33 | 8.0.4 - Bug #800
34 | 2.5.2 - Bug #770
35 |
--------------------------------------------------------------------------------
/tests/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # @(#) Integration tests
5 | #
6 |
7 | # have some limits...
8 | ulimit -n 50000
9 | ulimit -c unlimited
10 |
11 | # Load other config... stack size, etc
12 | source ~/ndrx_home
13 |
14 | #
15 | # Temporary fix for Support #754
16 | #
17 | export GODEBUG="asyncpreemptoff=1"
18 |
19 | > ./test.out
20 | # Have some terminal output...
21 | tail -f test.out &
22 |
23 | (
24 | M_tests=0
25 | M_ok=0
26 | M_fail=0
27 |
28 | run_test () {
29 |
30 | test=$1
31 | M_tests=$((M_tests + 1))
32 | echo "*** RUNNING [$test]"
33 |
34 | pushd .
35 | cd $test
36 | ./run.sh
37 | ret=$?
38 | popd
39 |
40 | echo "*** RESULT [$test] $ret"
41 |
42 | if [[ $ret -eq 0 ]]; then
43 | M_ok=$((M_ok + 1))
44 | else
45 | M_fail=$((M_fail + 1))
46 | fi
47 | }
48 |
49 | run_test "01_restin"
50 | run_test "02_tcpgatesv"
51 | run_test "03_restout"
52 |
53 | ################################################################################
54 | # Print results in out file
55 | # use temp file to avoid plotting to the same file which are are grepping...
56 | ################################################################################
57 | grep RESULT test.out >test.out.tmp
58 | cat test.out.tmp
59 | rm test.out.tmp
60 | ################################################################################
61 |
62 | echo "*** SUMMARY $M_tests tests executed. $M_ok passes, $M_fail failures"
63 |
64 | # wait for tail to pick the change
65 | sleep 5
66 | xadmin killall tail
67 |
68 | exit $M_fail
69 |
70 | ) > test.out 2>&1
71 |
72 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/cookies.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "ubftab"
5 |
6 | atmi "github.com/endurox-dev/endurox-go"
7 | )
8 |
9 | //Cookies UBF service
10 | //@param ac ATMI Context
11 | //@param svc Service call information
12 | func COOKIES(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
13 |
14 | ret := SUCCEED
15 |
16 | //Get UBF Handler
17 | ub, _ := ac.CastToUBF(&svc.Data)
18 |
19 | //Return to the caller
20 | defer func() {
21 | if SUCCEED == ret {
22 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
23 | } else {
24 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
25 | }
26 | }()
27 |
28 | //Resize buffer, to have some more space
29 | if err := ub.TpRealloc(1024); err != nil {
30 | ac.TpLogError("TpRealloc() Got error: %d:[%s]\n", err.Code(), err.Message())
31 | ret = FAIL
32 | return
33 | }
34 |
35 | //Print the buffer to stdout
36 | ub.TpLogPrintUBF(atmi.LOG_DEBUG, "Incoming request:")
37 |
38 | ac.TpLogDebug("Set Header & Cookies data")
39 |
40 | ub.BAdd(ubftab.EX_IF_RSPHN, "Accept-Language")
41 | ub.BAdd(ubftab.EX_IF_RSPHV, "EN-US")
42 |
43 | ub.BAdd(ubftab.EX_IF_RSPHN, "Last-Modified")
44 | ub.BAdd(ubftab.EX_IF_RSPHV, "Tue, 31 Aug 2063 23:59:59 GMT")
45 |
46 | // Set Cookie data
47 | ub.BAdd(ubftab.EX_IF_RSPCN, "RspCookie")
48 | ub.BAdd(ubftab.EX_IF_RSPCV, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq")
49 | ub.BAdd(ubftab.EX_IF_RSPCPATH, "/cookie/path")
50 | ub.BAdd(ubftab.EX_IF_RSPCDOMAIN, "localhost.com")
51 | ub.BAdd(ubftab.EX_IF_RSPCEXPIRES, "Thu, 08 Nov 2018 10:13:34 GMT")
52 | ub.BAdd(ubftab.EX_IF_RSPCMAXAGE, "3600")
53 | ub.BAdd(ubftab.EX_IF_RSPCSECURE, "AAA")
54 | ub.BAdd(ubftab.EX_IF_RSPCHTTPONLY, "true")
55 |
56 | ac.TpLogInfo("Got UBF: [%v]", ub)
57 |
58 | return
59 | }
60 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/conf/gencert.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Bash shell script for generating self-signed certs. Run this in a folder, as it
4 | # generates a few files. Large portions of this script were taken from the
5 | # following artcile:
6 | #
7 | # http://usrportage.de/archives/919-Batch-generating-SSL-certificates.html
8 | #
9 | # Additional alterations by: Brad Landers
10 | # Date: 2012-01-27
11 |
12 | # Script accepts a single argument, the fqdn for the cert
13 | DOMAIN="$1"
14 | if [ -z "$DOMAIN" ]; then
15 | echo "Usage: $(basename $0) "
16 | exit 11
17 | fi
18 |
19 | fail_if_error() {
20 | [ $1 != 0 ] && {
21 | unset PASSPHRASE
22 | exit 10
23 | }
24 | }
25 |
26 | # Generate a passphrase
27 | #export PASSPHRASE=$(head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c 128; echo)
28 | export PASSPHRASE=ABCDEFABCDEF
29 |
30 | # Certificate details; replace items in angle brackets with your own info
31 | subj="
32 | C=US
33 | ST=CA
34 | O=TEST
35 | localityName=NY
36 | commonName=$DOMAIN
37 | organizationalUnitName=EX
38 | emailAddress=test@example.com
39 | "
40 |
41 | # Generate the server private key
42 | openssl genrsa -des3 -out $DOMAIN.key -passout env:PASSPHRASE 2048
43 | fail_if_error $?
44 |
45 | # Generate the CSR
46 | openssl req \
47 | -new \
48 | -batch \
49 | -subj "$(echo -n "$subj" | tr "\n" "/")" \
50 | -key $DOMAIN.key \
51 | -out $DOMAIN.csr \
52 | -passin env:PASSPHRASE
53 | fail_if_error $?
54 | cp $DOMAIN.key $DOMAIN.key.org
55 | fail_if_error $?
56 |
57 | # Strip the password so we don't have to type it every time we restart Apache
58 | openssl rsa -in $DOMAIN.key.org -out $DOMAIN.key -passin env:PASSPHRASE
59 | fail_if_error $?
60 |
61 | # Generate the cert (good for 10 years)
62 | openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt
63 | fail_if_error $?
64 |
65 |
--------------------------------------------------------------------------------
/tests/01_restin/runtime/conf/gencert.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Bash shell script for generating self-signed certs. Run this in a folder, as it
4 | # generates a few files. Large portions of this script were taken from the
5 | # following artcile:
6 | #
7 | # http://usrportage.de/archives/919-Batch-generating-SSL-certificates.html
8 | #
9 | # Additional alterations by: Brad Landers
10 | # Date: 2012-01-27
11 |
12 | # Script accepts a single argument, the fqdn for the cert
13 | DOMAIN="$1"
14 | if [ -z "$DOMAIN" ]; then
15 | echo "Usage: $(basename $0) "
16 | exit 11
17 | fi
18 |
19 | fail_if_error() {
20 | [ $1 != 0 ] && {
21 | unset PASSPHRASE
22 | exit 10
23 | }
24 | }
25 |
26 | echo "OPENSSL USED: "
27 | which openssl
28 | echo "OPENSSL END"
29 |
30 | # Generate a passphrase
31 | #export PASSPHRASE=$(head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c 128; echo)
32 | export PASSPHRASE=ABCDEFABCDEF
33 | echo "PASSPHRASE: [$PASSPHRASE]"
34 |
35 | # Certificate details; replace items in angle brackets with your own info
36 | subj="
37 | C=US
38 | ST=CA
39 | O=TEST
40 | localityName=NY
41 | commonName=$DOMAIN
42 | organizationalUnitName=EX
43 | emailAddress=test@example.com
44 | "
45 |
46 | # Generate the server private key
47 | openssl genrsa -des3 -out $DOMAIN.key -passout env:PASSPHRASE 2048
48 | fail_if_error $?
49 |
50 | # Generate the CSR
51 | openssl req \
52 | -new \
53 | -batch \
54 | -subj "$(echo -n "$subj" | tr "\n" "/")" \
55 | -key $DOMAIN.key \
56 | -out $DOMAIN.csr \
57 | -passin env:PASSPHRASE
58 | fail_if_error $?
59 | cp $DOMAIN.key $DOMAIN.key.org
60 | fail_if_error $?
61 |
62 | # Strip the password so we don't have to type it every time we restart Apache
63 | openssl rsa -in $DOMAIN.key.org -out $DOMAIN.key -passin env:PASSPHRASE
64 | fail_if_error $?
65 |
66 | # Generate the cert (good for 10 years)
67 | openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt
68 | fail_if_error $?
69 |
70 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/src/testsv/seqtest.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | u "ubftab"
5 |
6 | atmi "github.com/endurox-dev/endurox-go"
7 | )
8 |
9 | var Msequence byte = 0
10 |
11 | var Mmsgs int64 = 0 //messages received
12 |
13 | //Test message sequence (seqin/seqout)
14 | //@param ac ATMI Context
15 | //@param svc Service call information
16 | func SEQTEST(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
17 |
18 | ret := SUCCEED
19 |
20 | //Return to the caller
21 | defer func() {
22 |
23 | ac.TpLogCloseReqFile()
24 | if SUCCEED == ret {
25 | ac.TpReturn(atmi.TPSUCCESS, 0, &svc.Data, 0)
26 | } else {
27 | ac.TpReturn(atmi.TPFAIL, 0, &svc.Data, 0)
28 | }
29 | }()
30 |
31 | //Get UBF Handler
32 | ub, _ := ac.CastToUBF(&svc.Data)
33 |
34 | //Print the buffer to stdout
35 | //fmt.Println("Incoming request:")
36 | ub.TpLogPrintUBF(atmi.LOG_DEBUG, "TESTSVC: Incoming request:")
37 |
38 | ba, err := ub.BGetByteArr(u.EX_NETDATA, 0)
39 |
40 | if err != nil {
41 | ac.TpLogError("TESTERROR Failed to get EX_NETDATA: %s", err.Message())
42 | ret = FAIL
43 | return
44 | }
45 |
46 | if ba[0] != Msequence {
47 |
48 | ac.TpLogError("TESTERROR: Expected %d got %d", Msequence, ba[0])
49 |
50 | }
51 |
52 | Mmsgs++;
53 | Msequence++
54 |
55 | return
56 | }
57 |
58 | //Return number of messages sequenced
59 | func SEQRES(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
60 |
61 | ret := SUCCEED
62 |
63 | //Return to the caller
64 | defer func() {
65 |
66 | ac.TpLogCloseReqFile()
67 | if SUCCEED == ret {
68 | ac.TpReturn(atmi.TPSUCCESS, 0, &svc.Data, 0)
69 | } else {
70 | ac.TpReturn(atmi.TPFAIL, 0, &svc.Data, 0)
71 | }
72 | }()
73 |
74 | //Get UBF Handler
75 | ub, _ := ac.CastToUBF(&svc.Data)
76 |
77 | used, _ := ub.BUsed()
78 |
79 | //Resize buffer, to have some more space
80 | if err := ub.TpRealloc(used + 1024); err != nil {
81 | ac.TpLogError("TpRealloc() Got error: %d:[%s]\n", err.Code(), err.Message())
82 | ret = FAIL
83 | return
84 | }
85 |
86 | if err := ub.BChg(u.T_LONG_FLD, 0, Mmsgs); nil != err {
87 | ac.TpLogError("Failed to set T_LONG_FLD: %s", err.Message())
88 | ret = FAIL
89 | return
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/jsonsv.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 |
6 | atmi "github.com/endurox-dev/endurox-go"
7 | )
8 |
9 | type TestJSONMsg struct {
10 | StringField string `json:"StringField"`
11 | StringField2 string `json:"StringField2"`
12 | NumField int `json:"NumField"`
13 | NumField2 int `json:"NumField2"`
14 | BoolField bool `json:"BoolField"`
15 | BoolField2 bool `json:"BoolField2"`
16 | }
17 |
18 | //JSON Service, we will receive JSON block
19 | //@param ac ATMI Context
20 | //@param svc Service call information
21 | func JSONSV(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
22 |
23 | var msg TestJSONMsg
24 | ret := SUCCEED
25 |
26 | //Get UBF Handler
27 | jb, _ := ac.CastToJSON(&svc.Data)
28 |
29 | //Return to the caller
30 | defer func() {
31 | if SUCCEED == ret {
32 | ac.TpReturn(atmi.TPSUCCESS, 0, jb, 0)
33 | } else {
34 | ac.TpReturn(atmi.TPFAIL, 0, jb, 0)
35 | }
36 | }()
37 |
38 | ac.TpLogWarn("Got json request...")
39 |
40 | //Resize buffer, to have some more space to return data in
41 | if err := jb.TpRealloc(1024); err != nil {
42 | ac.TpLogError("TpRealloc() Got error: %d:[%s]\n",
43 | err.Code(), err.Message())
44 | ret = FAIL
45 | return
46 | }
47 |
48 | ac.TpLogDump(atmi.LOG_INFO, "Got request buffer",
49 | jb.GetJSON(), len(jb.GetJSON()))
50 | //Umarshal the data, copy to *2 and marshal back to buffer
51 | jerr := json.Unmarshal(jb.GetJSON(), &msg)
52 | if jerr != nil {
53 | ac.TpLogError("Unmarshal: %s", jerr)
54 | ret = FAIL
55 | return
56 | }
57 | msg.StringField2 = msg.StringField
58 | msg.BoolField2 = msg.BoolField
59 | msg.NumField2 = msg.NumField
60 |
61 | val, jerr := json.Marshal(msg)
62 | if jerr != nil {
63 | ac.TpLogError("Marshal: %s", jerr)
64 | ret = FAIL
65 | return
66 | }
67 |
68 | ac.TpLogDump(atmi.LOG_INFO, "Built response", val, len(val))
69 |
70 | //Set the data in return buffer
71 | if err := jb.SetJSON(val); err != nil {
72 | ac.TpLogError("Failed to return json buffer %s", err.Message())
73 | ret = FAIL
74 | return
75 | }
76 |
77 | ac.TpLogDump(atmi.LOG_INFO, "Responding with buffer", jb.GetJSON(), len(jb.GetJSON()))
78 |
79 | return
80 | }
81 |
--------------------------------------------------------------------------------
/doc/manpage/Makefile:
--------------------------------------------------------------------------------
1 | ##
2 | ## @brief Enduro/X Addons (connectivity) module documentation
3 | ##
4 | ## @file Makefile
5 | ##
6 | ## -----------------------------------------------------------------------------
7 | ## Enduro/X Middleware Platform for Distributed Transaction Processing
8 | ## Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | ## Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | ## This software is released under one of the following licenses:
11 | ## AGPL or Mavimax's license for commercial use.
12 | ## -----------------------------------------------------------------------------
13 | ## AGPL license:
14 | ##
15 | ## This program is free software; you can redistribute it and/or modify it under
16 | ## the terms of the GNU Affero General Public License, version 3 as published
17 | ## by the Free Software Foundation;
18 | ##
19 | ## This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | ## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | ## PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | ## for more details.
23 | ##
24 | ## You should have received a copy of the GNU Affero General Public License along
25 | ## with this program; if not, write to the Free Software Foundation, Inc.,
26 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | ##
28 | ## -----------------------------------------------------------------------------
29 | ## A commercial use license is available from Mavimax, Ltd
30 | ## contact@mavimax.com
31 | ## -----------------------------------------------------------------------------
32 | ##
33 |
34 | A2X := $(shell a2x --version 2> /dev/null)
35 |
36 | SOURCE_DOCS :=$(shell ls -1 *.adoc)
37 | DOCS := $(patsubst %.adoc, %.8, $(SOURCE_DOCS))
38 |
39 | .DEFAULT_GOAL := all
40 |
41 | check_asciidoc:
42 | @type a2x >/dev/null 2>&1 || echo "Missing asciidoc - docs will not built"
43 |
44 | all: check_asciidoc $(DOCS)
45 |
46 | #
47 | # Do not remove images
48 | #
49 | .SECONDARY: $(GRAPHS)
50 |
51 |
52 | #
53 | # Build the document
54 | # So translate the % document and use $%
55 | #
56 | %.8: %.adoc
57 | a2x -D. --format=manpage $<
58 | a2x -D. --format=xhtml $<
59 |
60 | clean:
61 | rm -f *.8 *.html *.css
62 |
63 | .PHONY: clean all
64 |
65 |
66 |
67 | # vim: set ts=4 sw=4 et smartindent:
68 |
--------------------------------------------------------------------------------
/tests/03_restout/src/bigmsgsv/testsv.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | u "ubftab"
8 |
9 | atmi "github.com/endurox-dev/endurox-go"
10 | )
11 |
12 | const (
13 | SUCCEED = 0
14 | FAIL = -1
15 | )
16 |
17 | //BIGMSG service
18 | func BIGMSG(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
19 |
20 | ret := SUCCEED
21 |
22 | //Get UBF Handler
23 | ub, _ := ac.CastToUBF(&svc.Data)
24 |
25 | //Print the buffer to stdout
26 | //fmt.Println("Incoming request:")
27 | //ub.TpLogPrintUBF(atmi.LOG_DEBUG, "Incoming request:")
28 | ac.TpLogInfo("BIGMSG got call!")
29 |
30 | //Set some field
31 | testdata, err := ub.BGetByteArr(u.T_CARRAY_FLD, 0)
32 |
33 | if err != nil {
34 | fmt.Printf("Bchg() Got error: %d:[%s]\n", err.Code(), err.Message())
35 | ret = FAIL
36 | goto out
37 | }
38 |
39 | for i := 0; i < len(testdata); i++ {
40 | if testdata[i] != byte((i+1)%255) {
41 | ac.TpLogError("TESTERROR: Error at index %d expected %d got: %d",
42 | i, (i+2)%255, testdata[i])
43 | ret = FAIL
44 | goto out
45 | }
46 |
47 | testdata[i] = byte((i + 2) % 255)
48 | }
49 |
50 | ac.TpLogInfo("About set test data!")
51 |
52 | if err := ub.BChg(u.T_CARRAY_FLD, 0, testdata); err != nil {
53 | ac.TpLogError("TESTERROR ! Bchg() 2 Got error: %d:[%s]", err.Code(), err.Message())
54 | ret = FAIL
55 | goto out
56 | }
57 |
58 | out:
59 | //Return to the caller
60 | if SUCCEED == ret {
61 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
62 | } else {
63 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
64 | }
65 | return
66 | }
67 |
68 | //Server init, called when process is booted
69 | //@param ac ATMI Context
70 | func Init(ac *atmi.ATMICtx) int {
71 |
72 | ac.TpLogWarn("Doing server init...")
73 |
74 | if err := ac.TpAdvertise("BIGMSG", "BIGMSG", BIGMSG); err != nil {
75 | fmt.Println(err)
76 | return atmi.FAIL
77 | }
78 |
79 | return atmi.SUCCEED
80 | }
81 |
82 | //Server shutdown
83 | //@param ac ATMI Context
84 | func Uninit(ac *atmi.ATMICtx) {
85 | ac.TpLogWarn("Server is shutting down...")
86 | }
87 |
88 | //Executable main entry point
89 | func main() {
90 | //Have some context
91 | ac, err := atmi.NewATMICtx()
92 |
93 | if nil != err {
94 | fmt.Fprintf(os.Stderr, "Failed to allocate new context: %s", err)
95 | os.Exit(atmi.FAIL)
96 | } else {
97 | //Run as server
98 | ac.TpRun(Init, Uninit)
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/go/src/exutil/stopwatch.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Simple stopwatch implementation
3 | *
4 | * @file stopwatch.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package exutil
34 |
35 | import (
36 | "time"
37 | )
38 |
39 | //Get UTC milliseconds since epoch
40 | //@return epoch milliseconds
41 | func GetEpochMillis() int64 {
42 | now := time.Now()
43 | nanos := now.UnixNano()
44 | millis := nanos / 1000000
45 |
46 | return millis
47 | }
48 |
49 | //About incoming & outgoing messages:
50 | type StopWatch struct {
51 | start int64 //Timestamp messag sent
52 | }
53 |
54 | //Reset the stopwatch
55 | func (s *StopWatch) Reset() {
56 | s.start = GetEpochMillis()
57 | }
58 |
59 | //Get delta milliseconds
60 | //@return time spent in milliseconds
61 | func (s *StopWatch) GetDeltaMillis() int64 {
62 | return GetEpochMillis() - s.start
63 | }
64 |
65 | //Get delta seconds of the stopwatch
66 | //@return return seconds spent
67 | func (s *StopWatch) GetDetlaSec() int64 {
68 | return (GetEpochMillis() - s.start) / 1000
69 | }
70 | /* vim: set ts=4 sw=4 et smartindent: */
71 |
--------------------------------------------------------------------------------
/doc/Mdoc:
--------------------------------------------------------------------------------
1 | ##
2 | ## @brief Enduro/X Addons (connectivity) module documentation
3 | ##
4 | ## @file Mdoc
5 | ##
6 | ## -----------------------------------------------------------------------------
7 | ## Enduro/X Middleware Platform for Distributed Transaction Processing
8 | ## Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | ## Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | ## This software is released under one of the following licenses:
11 | ## AGPL or Mavimax's license for commercial use.
12 | ## -----------------------------------------------------------------------------
13 | ## AGPL license:
14 | ##
15 | ## This program is free software; you can redistribute it and/or modify it under
16 | ## the terms of the GNU Affero General Public License, version 3 as published
17 | ## by the Free Software Foundation;
18 | ##
19 | ## This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | ## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | ## PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | ## for more details.
23 | ##
24 | ## You should have received a copy of the GNU Affero General Public License along
25 | ## with this program; if not, write to the Free Software Foundation, Inc.,
26 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | ##
28 | ## -----------------------------------------------------------------------------
29 | ## A commercial use license is available from Mavimax, Ltd
30 | ## contact@mavimax.com
31 | ## -----------------------------------------------------------------------------
32 | ##
33 |
34 | A2X := $(shell a2x --version 2> /dev/null)
35 |
36 | SOURCE_DOCS :=$(shell ls -1 *.adoc)
37 | DOCS := $(patsubst %.adoc, %.html, $(SOURCE_DOCS))
38 |
39 | SOURCES_GRAPHS :=$(shell ls -1 *.dia)
40 | GRAPHS := $(patsubst %.dia, %.png, $(SOURCES_GRAPHS))
41 |
42 | $(info $$SOURCES_GRAPHS is [${SOURCES_GRAPHS}])
43 | $(info $$GRAPHS is [${GRAPHS}])
44 |
45 | .DEFAULT_GOAL := all
46 |
47 | check_asciidoc:
48 | @type a2x >/dev/null 2>&1 || echo "Missing asciidoc - docs will not built"
49 |
50 | check_dia:
51 | @type dia >/dev/null 2>&1 || echo "Missing asciidoc - docs will not built"
52 |
53 | all: check_asciidoc check_dia $(DOCS)
54 |
55 | #
56 | # Do not remove images
57 | #
58 | .SECONDARY: $(GRAPHS)
59 |
60 |
61 | #
62 | # Build the images
63 | # Images shall go to "images" folder
64 | # and later shall be copied to "out"/images
65 | #
66 | %.png: %.dia
67 | dia --size=800x --filter=png -e $@ -t png $<
68 |
69 | #
70 | # Build the document
71 | # So translate the % document and use $%
72 | #
73 | %.html: %.adoc $(GRAPHS)
74 | a2x -D. -f xhtml $<
75 |
76 | clean:
77 | rm -f *.html *.css *.xml *.png
78 |
79 | .PHONY: clean all
80 |
81 |
82 |
83 | # vim: set ts=4 sw=4 et smartindent:
84 |
--------------------------------------------------------------------------------
/go/src/restoutsv/periodic.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Enduro/X periodic service polling callback (using for echo advertise)
3 | *
4 | * @file periodic.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | atmi "github.com/endurox-dev/endurox-go"
37 | )
38 |
39 | //Run scheduled tasks for advertise/unadvertise
40 | //@param ac ATMI Context (server main)
41 | //@return SUCCEED 0, or -1 FAIL
42 | func Periodic(ac *atmi.ATMICtx) int {
43 |
44 | ret := atmi.SUCCEED
45 |
46 | ac.TpLogDebug("Periodic()")
47 |
48 | MadvertiseLock.Lock()
49 |
50 | //Loop over the all services and check the required actions
51 | for _, v := range Mservices {
52 |
53 | if v.echoSchedAdv {
54 |
55 | ac.TpLogInfo("periodic: [%s] needs to be advertised",
56 | v.Svc)
57 |
58 | if errA := v.Advertise(ac); errA != nil {
59 |
60 | ac.TpLogError("Failed to advertise [%s]: %s",
61 | v.Svc, errA.Error())
62 |
63 | return FAIL
64 | }
65 |
66 | } else if v.echoSchedUnAdv {
67 |
68 | ac.TpLogInfo("periodic: [%s] needs to be unadvertised",
69 | v.Svc)
70 | if errA := v.Unadvertise(ac); errA != nil {
71 |
72 | ac.TpLogError("Failed to unadvertise [%s]: %s",
73 | v.Svc, errA.Error())
74 |
75 | return FAIL
76 | }
77 | }
78 | }
79 |
80 | MadvertiseLock.Unlock()
81 |
82 | return ret
83 | }
84 | /* vim: set ts=4 sw=4 et smartindent: */
85 |
--------------------------------------------------------------------------------
/go/src/exutil/caroots.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief CA Root handler
3 | *
4 | * @file caroots.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package exutil
34 |
35 | import (
36 | "crypto/x509"
37 | "fmt"
38 | "io/ioutil"
39 | "strings"
40 |
41 | atmi "github.com/endurox-dev/endurox-go"
42 | )
43 |
44 | var MRootCAs *x509.CertPool = nil //Loaded root cer
45 |
46 | //Load root certificate authorities from configured string
47 | func LoadRootCAs(ac *atmi.ATMICtx, carootsfiles string) error {
48 |
49 | //Split by ;
50 | certs := strings.Replace(carootsfiles, " ", "", -1)
51 | certs = strings.Replace(carootsfiles, "\t", "", -1)
52 |
53 | crt_arr := strings.Split(certs, ";")
54 | crt_num := len(crt_arr)
55 |
56 | MRootCAs = x509.NewCertPool()
57 |
58 | for i := 0; i < crt_num; i++ {
59 |
60 | ac.TpLogInfo("Loading root CA: %s", crt_arr[i])
61 |
62 | caCert, err := ioutil.ReadFile(crt_arr[i])
63 | if err != nil {
64 | ac.TpLogError("Failed to read CA root cert [%s]: %s", crt_arr[i], err)
65 | return fmt.Errorf("Failed to read CA root cert [%s]: %s", crt_arr[i], err)
66 | }
67 | if !MRootCAs.AppendCertsFromPEM(caCert) {
68 | ac.TpLogError("Failed to load/parse CA root cert [%s]", crt_arr[i])
69 | return fmt.Errorf("Failed to load/parse CA root cert [%s]", crt_arr[i])
70 | }
71 | }
72 |
73 | ac.TpLogInfo("Roots loaded OK")
74 | return nil
75 |
76 | }
77 |
78 | /* vim: set ts=4 sw=4 et smartindent: */
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # endurox-connect
2 | Enduro/X Connectivity packages
3 |
4 | This module adds ability to expose to outer world Enduro/X services. It is bi-directional interface, providing:
5 |
6 | * Incoming from network http/rest compatibility. This process allows to configure web route and map them to internal XATMI services. The configuration is extensible and there are several data conversion formats available.
7 | * Outgoing to network http/rest compatibility.
8 | * Generic two-way tcp/ip driver for IoT device connectivity.
9 |
10 | Release binaries may be found here: https://www.mavimax.com/downloads
11 |
12 | ## Build & test status
13 |
14 | | OS | Status | OS | Status |OS | Status |
15 | |----------|:-------------:|----------|:-------------:|----------|:-------------:|
16 | |RHEL/Oracle Linux 8| [](http://www.silodev.com:9090/jenkins/job/endurox-connect-ol8/) | Centos 6|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-centos6/)|FreeBSD 11|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-freebsd11/)|
17 | |Oracle Linux 7|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-ol7/)|OSX 11.4|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-osx11_4/)|raspbian10_arv7l|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-raspbian10_arv7l/)|
18 | |SLES 12|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-sles12/)|SLES 15|[](http://www.silodev.com:9090/jenkins/job/endurox-connect-sles15/)|Ubuntu 14.04| [](http://www.silodev.com:9090/jenkins/job/endurox-connect-ubuntu14/)|
19 | |Ubuntu 18.04| [](http://www.silodev.com:9090/jenkins/job/endurox-connect-ubuntu18/)|AIX 7.2| [](http://www.silodev.com:9090/jenkins/job/endurox-connect-aix7_2/)|
20 |
21 |
22 | # Releases
23 |
24 | - Version 8.0.0 released on 09/01/2022 (stable) Support #754, Bug #757
25 | - Version 8.0.2 released on 07/04/2022 (stable) Bug #770, Support #780
26 | - Version 2.5.2 released on 07/04/2022 (stable) Bug #770
27 | - Version 8.0.4 released on 07/03/2023 (stable) Bug #800
28 | - Version 2.5.4 released on 03/04/2024 (stable) Bug #828
29 | - Version 8.0.6 released on 03/04/2024 (stable) Bug #828
30 | - Version 2.5.6 marked on 22/09/2024 (stable) Feature #846
31 | - Version 8.0.6 marked on 22/09/2024 (stable) Feature #846
32 |
--------------------------------------------------------------------------------
/go/src/restoutsv/jsonerror.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Parse the incoming json message and read the fields cotnaining json string & Number
3 | * This will use Enduro/X provided Exparson package. Due to fact that there are
4 | * problems with golang to dynamicall parse the string & number in one step.
5 | *
6 | * @file jsonerror.go
7 | */
8 | /* -----------------------------------------------------------------------------
9 | * Enduro/X Middleware Platform for Distributed Transaction Processing
10 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
11 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
12 | * This software is released under one of the following licenses:
13 | * AGPL or Mavimax's license for commercial use.
14 | * -----------------------------------------------------------------------------
15 | * AGPL license:
16 | *
17 | * This program is free software; you can redistribute it and/or modify it under
18 | * the terms of the GNU Affero General Public License, version 3 as published
19 | * by the Free Software Foundation;
20 | *
21 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
22 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
23 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
24 | * for more details.
25 | *
26 | * You should have received a copy of the GNU Affero General Public License along
27 | * with this program; if not, write to the Free Software Foundation, Inc.,
28 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 | *
30 | * -----------------------------------------------------------------------------
31 | * A commercial use license is available from Mavimax, Ltd
32 | * contact@mavimax.com
33 | * -----------------------------------------------------------------------------
34 | */
35 | package main
36 |
37 | import (
38 | "unsafe"
39 | "errors"
40 | atmi "github.com/endurox-dev/endurox-go"
41 | )
42 |
43 | /*
44 | #cgo pkg-config: atmisrvinteg
45 |
46 | #include
47 | #include
48 | */
49 | import "C"
50 |
51 | //Get the JSON error fields (if they are present)
52 | //@param ac ATMI context
53 | //@param json JSON block recevied from network
54 | //@return , , ATMIError (if set to nil, all other are present)
55 | func JSONErrorGet(ac *atmi.ATMICtx, json *string, jcodefld string, jmessagefld string) (int, string, error) {
56 |
57 | c_codefld := C.CString(jcodefld)
58 | defer C.free(unsafe.Pointer(c_codefld))
59 |
60 | c_jmessagefld := C.CString(jmessagefld)
61 | defer C.free(unsafe.Pointer(c_jmessagefld))
62 |
63 | c_buffer := C.CString(*json)
64 | defer C.free(unsafe.Pointer(c_buffer))
65 |
66 | root_value := C.exjson_parse_string_with_comments(c_buffer);
67 | defer C.exjson_value_free(root_value);
68 |
69 | if nil==root_value {
70 | return FAIL, "", errors.New("Invalid JSON (1)!");
71 | }
72 |
73 | root_object := C.exjson_value_get_object(root_value);
74 |
75 | if nil==root_object {
76 | return FAIL, "", errors.New("Invalid JSON (2)!");
77 | }
78 |
79 | if (nil!=root_object) {
80 |
81 | codeVal:=C.exjson_object_dotget_number(root_object, c_codefld)
82 | messageVal:=C.exjson_object_get_string(root_object, c_jmessagefld)
83 |
84 | errs:=C.GoString(messageVal)
85 |
86 | if errs=="" {
87 | ac.TpLogInfo("No error string in response");
88 | }
89 |
90 | return int(C.int(codeVal)), C.GoString(messageVal), nil
91 | }
92 |
93 | return FAIL, "", errors.New("Invalid JSON (3)");
94 | }
95 | /* vim: set ts=4 sw=4 et smartindent: */
96 |
--------------------------------------------------------------------------------
/go/src/tcpgatesv/xatmipool.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Pool of XATMI sessions
3 | *
4 | * @file xatmipool.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "sync"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | type XATMIPool struct {
42 | //freechansync *sync.Mutex //We need to lock the freechan
43 | freechan chan int //List of free channels submitted by wokers
44 | ctxs []*atmi.ATMICtx //List of contexts
45 | nrWorkers int //Number of contexts
46 |
47 | }
48 |
49 | var MinXPool XATMIPool //In XATMI pool
50 | var MoutXPool XATMIPool //Out XATMI pool
51 |
52 | var MXDispatcher = &sync.Mutex{}
53 |
54 | //Initialize out pool
55 | //@param ac ATMI contexts
56 | //@param pool XATMI pool
57 | //@return error in case of error or nil if ok
58 | func initPool(ac *atmi.ATMICtx, pool *XATMIPool) error {
59 |
60 | pool.freechan = make(chan int, pool.nrWorkers)
61 |
62 | //pool.freechansync = &sync.Mutex{}
63 |
64 | for i := 0; i < pool.nrWorkers; i++ {
65 |
66 | ctx, err := atmi.NewATMICtx()
67 |
68 | if err != nil {
69 | ac.TpLogError("Failed to create context: %s", err.Message())
70 | return err
71 | }
72 |
73 | if err := ctx.TpInit(); nil != err {
74 | ac.TpLogError("Failed to tpinit: %s", err.Error())
75 | return err
76 | }
77 |
78 | pool.ctxs = append(pool.ctxs, ctx)
79 |
80 | //Submit the free ATMI context
81 | pool.freechan <- i
82 | }
83 | return nil
84 | }
85 |
86 | //Close the open xatmi contexts
87 | //@param ac XATMI contexts
88 | //@param pool XATMI pool
89 | func deInitPoll(ac *atmi.ATMICtx, pool *XATMIPool) {
90 |
91 | for i := 0; i < pool.nrWorkers; i++ {
92 | nr := <-pool.freechan
93 |
94 | ac.TpLogWarn("Terminating %d context", nr)
95 | pool.ctxs[nr].TpTerm()
96 | pool.ctxs[nr].FreeATMICtx()
97 | }
98 | }
99 |
100 | //Return the free X context
101 | func getFreeXChan(ac *atmi.ATMICtx, pool *XATMIPool) int {
102 | //Should we use locking here?
103 | //WHY?
104 | //pool.freechansync.Lock()
105 |
106 | nr := <-pool.freechan
107 |
108 | //pool.freechansync.Unlock()
109 |
110 | ac.TpLogInfo("Got free XATMI out object id=%d ", nr)
111 |
112 | return nr
113 | }
114 |
115 | /* vim: set ts=4 sw=4 et smartindent: */
116 |
--------------------------------------------------------------------------------
/go/src/restoutsv/xatmipool.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Pool of XATMI sessions
3 | *
4 | * @file xatmipool.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "sync"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | type XATMIPool struct {
42 | freechansync *sync.Mutex //We need to lock the freechan
43 | freechan chan int //List of free channels submitted by wokers
44 | ctxs []*atmi.ATMICtx //List of contexts
45 | nrWorkers int //Number of contexts
46 |
47 | }
48 |
49 | var MoutXPool XATMIPool //Out XATMI pool
50 |
51 | var MXDispatcher = &sync.Mutex{}
52 |
53 | //Initialize out pool
54 | //@param ac ATMI contexts
55 | //@param pool XATMI pool
56 | //@return error in case of error or nil if ok
57 | func initPool(ac *atmi.ATMICtx, pool *XATMIPool) atmi.ATMIError {
58 |
59 | pool.freechan = make(chan int, pool.nrWorkers)
60 |
61 | pool.freechansync = &sync.Mutex{}
62 |
63 | for i := 0; i < pool.nrWorkers; i++ {
64 |
65 | ctx, err := atmi.NewATMICtx()
66 |
67 | if err != nil {
68 | ac.TpLogError("Failed to create context: %s", err.Message())
69 | return err
70 | }
71 |
72 | //Causes auto-init to kill the last-call object
73 | if err := ctx.TpInit(); nil != err {
74 | ac.TpLogError("Failed to tpinit: %s", err.Error())
75 | return err
76 | }
77 |
78 | pool.ctxs = append(pool.ctxs, ctx)
79 |
80 | //Submit the free ATMI context
81 | pool.freechan <- i
82 | }
83 | return nil
84 | }
85 |
86 | //Close the open xatmi contexts
87 | //@param ac XATMI contexts
88 | //@param pool XATMI pool
89 | func deInitPoll(ac *atmi.ATMICtx, pool *XATMIPool) {
90 |
91 | for i := 0; i < pool.nrWorkers; i++ {
92 | nr := <-pool.freechan
93 |
94 | ac.TpLogWarn("Terminating %d context", nr)
95 | pool.ctxs[nr].TpTerm()
96 | pool.ctxs[nr].FreeATMICtx()
97 | }
98 | }
99 |
100 | //Return the free X context
101 | func getFreeXChan(ac *atmi.ATMICtx, pool *XATMIPool) int {
102 | //Should we use locking here?
103 |
104 | pool.freechansync.Lock()
105 |
106 | nr := <-pool.freechan
107 |
108 | pool.freechansync.Unlock()
109 |
110 | ac.TpLogInfo("Got free XATMI out object id=%d ", nr)
111 |
112 | return nr
113 | }
114 | /* vim: set ts=4 sw=4 et smartindent: */
115 |
--------------------------------------------------------------------------------
/tests/01_restin/src/transv/transv.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Transaction queue interface service. This will add message to queue
3 | * and read message from queue. The caller via restincl will control the transactions
4 | * and thus add/gets should follow the transactional nature.
5 | *
6 | * @file transv.go
7 | */
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "os"
13 | "ubftab"
14 |
15 | atmi "github.com/endurox-dev/endurox-go"
16 | )
17 |
18 | //Add message to queue
19 | //@param ac ATMI Context
20 | //@param svc Service call information
21 | func QADD(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
22 |
23 | ret := atmi.SUCCEED
24 |
25 | var qctl atmi.TPQCTL
26 | //Get UBF Handler
27 | ub, _ := ac.CastToUBF(&svc.Data)
28 |
29 | //Return to the caller
30 | defer func() {
31 |
32 | ac.TpLogCloseReqFile()
33 | if atmi.SUCCEED == ret {
34 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
35 | } else {
36 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
37 | }
38 | }()
39 |
40 | //Print the buffer to stdout
41 | ub.TpLogPrintUBF(atmi.LOG_DEBUG, "Incoming request:")
42 |
43 | //Enqueue the string
44 | if err := ac.TpEnqueue("QSPACE1", "MYQ1", &qctl, ub, 0); nil != err {
45 | fmt.Printf("TpEnqueue() failed: ATMI Error %d:[%s]\n", err.Code(), err.Message())
46 | ret = atmi.FAIL
47 | return
48 | }
49 |
50 | return
51 | }
52 |
53 | //Get message from queue
54 | //@param ac ATMI Context
55 | //@param svc Service call information
56 | func QGET(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
57 |
58 | var qctl atmi.TPQCTL
59 |
60 | ret := atmi.SUCCEED
61 | //Get UBF Handler
62 | ub, _ := ac.CastToUBF(&svc.Data)
63 |
64 | //Return to the caller
65 | defer func() {
66 |
67 | ac.TpLogCloseReqFile()
68 | if atmi.SUCCEED == ret {
69 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
70 | } else {
71 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
72 | }
73 | }()
74 |
75 | //Resize buffer, to have some more space
76 | used, _ := ub.BUsed()
77 | if err := ub.TpRealloc(used + 1024); err != nil {
78 | ac.TpLogError("TpRealloc() Got error: %d:[%s]\n", err.Code(), err.Message())
79 | ret = atmi.FAIL
80 | return
81 | }
82 |
83 | //Get the msg
84 | if err := ac.TpDequeue("QSPACE1", "MYQ1", &qctl, &svc.Data, 0); nil != err {
85 | fmt.Printf("TpDequeue() failed: ATMI Error %d:[%s]\n", err.Code(), err.Message())
86 | ret = atmi.FAIL
87 |
88 | //Load the error code of Q
89 | ub.BChg(ubftab.T_LONG_2_FLD, 0, err.Code())
90 |
91 | return
92 | }
93 |
94 | return
95 | }
96 |
97 | //TXFAIL generate fail (note that this is process in transaction context)
98 | //@param ac ATMI Context
99 | //@param svc Service call information
100 | func TXFAIL(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
101 |
102 | ac.TpReturn(atmi.TPFAIL, 0, &svc.Data, 0)
103 |
104 | return
105 | }
106 |
107 | //Server init, called when process is booted
108 | //@param ac ATMI Context
109 | func Init(ac *atmi.ATMICtx) int {
110 |
111 | ac.TpLogWarn("Doing server init...")
112 |
113 | if err := ac.TpAdvertise("QADD", "QADD", QADD); err != nil {
114 | fmt.Println(err)
115 | return atmi.FAIL
116 | }
117 |
118 | if err := ac.TpAdvertise("QGET", "QGET", QGET); err != nil {
119 | fmt.Println(err)
120 | return atmi.FAIL
121 | }
122 |
123 | if err := ac.TpAdvertise("TXFAIL", "TXFAIL", TXFAIL); err != nil {
124 | fmt.Println(err)
125 | return atmi.FAIL
126 | }
127 |
128 | if err := ac.TpOpen(); err != nil {
129 | ac.TpLogError("Failed to tpopen: %s", err.Error())
130 | return atmi.FAIL
131 | }
132 |
133 | return atmi.SUCCEED
134 | }
135 |
136 | //Server shutdown
137 | //@param ac ATMI Context
138 | func Uninit(ac *atmi.ATMICtx) {
139 | ac.TpLogWarn("Server is shutting down...")
140 | ac.TpClose()
141 | }
142 |
143 | //Executable main entry point
144 | func main() {
145 | //Have some context
146 | ac, err := atmi.NewATMICtx()
147 |
148 | if nil != err {
149 | fmt.Fprintf(os.Stderr, "Failed to allocate new context: %s", err)
150 | os.Exit(atmi.FAIL)
151 | } else {
152 | //Run as server
153 | ac.TpRun(Init, Uninit)
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/tests/01_restin/runtime/conf/ndrxconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
12 | 1
13 |
14 |
17 | 5
18 |
19 |
22 | 1
23 |
24 |
27 | 1
28 |
29 |
32 | 5
33 |
34 |
37 |
38 |
42 | 20
43 |
44 |
45 |
50 | Y
51 |
52 |
53 |
54 |
55 | 1
56 | 2
57 |
58 |
61 | 1
62 |
63 |
67 | 2
68 |
69 |
72 | 10
73 |
74 |
79 | 30
80 |
81 |
85 | 3
86 |
87 |
91 | 1
92 |
93 |
94 |
95 |
96 | 2
97 | 2
98 | 1
99 | -e ${NDRX_APPHOME}/log/cconfsrv.log -r
100 |
101 |
102 | 2
103 | 2
104 | 20
105 | -e ${NDRX_APPHOME}/log/tpevsrv.log -r
106 |
107 |
108 | 1
109 | 1
110 | TRAN
111 | 200
112 | -e ${NDRX_APPHOME}/log/tmsrv-rm1.log -r -- -t1 -l${NDRX_APPHOME}/tmlogs/rm2
113 |
114 |
115 | 1
116 | 1
117 | 240
118 | TMQ
119 | -e ${NDRX_APPHOME}/log/tmsrv-rm1.log -r -- -t1 -l${NDRX_APPHOME}/tmlogs/rm2
120 |
121 |
122 | 1
123 | 1
124 | 300
125 | TMQ
126 | -e ${NDRX_APPHOME}/log/tmqueue-rm2.log -r -- -s1
127 |
128 |
129 | 1
130 | 1
131 | 2000
132 | -e ${NDRX_APPHOME}/log/testsv.log -r
133 |
134 |
135 | 1
136 | 1
137 | 2020
138 | TRAN
139 | -e ${NDRX_APPHOME}/log/transv.log -r
140 |
141 |
142 | 1
143 | 1
144 | 9999
145 | -e ${NDRX_APPHOME}/log/cpmsrv.log -r -- -k3 -i1
146 |
147 |
148 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
--------------------------------------------------------------------------------
/go/src/restoutsv/viewsupp.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief View support routines
3 | *
4 | * @file viewsupp.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "fmt"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | //Install error code in the view, Note max allowed error message size is 1024 bytes
42 | //including EOS
43 | //@param buf VIEW buffer
44 | //@param code error code to install
45 | //@param msg error message to install
46 | //@return nil on OK, UBF error on failure
47 | func VIEWInstallError(buf *atmi.TypedVIEW, view string, view_code_fld string,
48 | code int, view_msg_fld string, msg string) atmi.UBFError {
49 |
50 | //Check the length of the message field
51 |
52 | _, _, _, dim_size, _, errU := buf.BVOccur(view_msg_fld)
53 |
54 | if nil != errU {
55 | buf.Buf.Ctx.TpLogError("Failed to get %s.%s infos: %s",
56 | view, view_msg_fld, errU.Error())
57 | return errU
58 | }
59 |
60 | buf.Buf.Ctx.TpLogInfo("message field dim size: %d", dim_size)
61 | //Conver message to bytes:
62 |
63 | byteStr := []byte(msg)
64 |
65 | //+1 for C EOS
66 | if int64(len(byteStr)+1) > dim_size {
67 | byteStr = byteStr[0 : dim_size-1] //1 for EOS
68 | }
69 |
70 | if errU := buf.BVChg(view_code_fld, 0, code); nil != errU {
71 | buf.Buf.Ctx.TpLogError("Failed to test/set code in resposne %s.[%s] to [%d]: %s",
72 | view, view_code_fld, code, errU.Error())
73 | return errU
74 | }
75 |
76 | if errU := buf.BVChg(view_msg_fld, 0, byteStr); nil != errU {
77 | buf.Buf.Ctx.TpLogError("Failed to test/set message in resposne %s.[%s] to [%d]: %s",
78 | view, view_msg_fld, string(byteStr), errU.Error())
79 | return errU
80 | }
81 |
82 | return nil
83 | }
84 |
85 | //Validate view service
86 | //@param ac ATMI Service context
87 | //@param s Service context
88 | //@return error in case of err or nil
89 | func VIEWValidateService(ac *atmi.ATMICtx, s *ServiceMap) error {
90 |
91 | //Set not NULL flag
92 | if s.View_notnull {
93 | ac.TpLogInfo("VIEWs in responses will contain non NULL fields only " +
94 | "(according to view file)")
95 | s.View_flags |= atmi.BVACCESS_NOTNULL
96 | }
97 |
98 | if ERRORS_JSON2VIEW == s.Errors_int &&
99 | (s.Errfmt_view_code == "" || s.Errfmt_view_msg == "") {
100 | return fmt.Errorf("For json2view errors parameters 'errfmt_view_code' and " +
101 | "'errfmt_view_msg' must be defined")
102 | }
103 |
104 | return nil
105 | }
106 |
107 | //Reset view error
108 | //@param ac ATMI Context
109 | //@param s service map
110 | //@param v typed view
111 | //@return in case of error ATMI error or nil
112 | func VIEWResetEchoError(ac *atmi.ATMICtx, s *ServiceMap, v *atmi.TypedVIEW) atmi.ATMIError {
113 |
114 | if s.Errors_int == ERRORS_JSON2VIEW {
115 | errU := VIEWInstallError(s.echoVIEW, s.echoVIEW.BVName(), s.Errfmt_view_code,
116 | atmi.TPMINVAL, s.Errfmt_view_msg, "SUCCEED")
117 | if nil != errU {
118 | ac.TpLogError("Failed to install response in echo view: %s",
119 | errU.Error())
120 | return atmi.NewCustomATMIError(atmi.TPEINVAL, fmt.Sprintf("Failed to install "+
121 | "response in echo view: %s", errU.Error()))
122 | }
123 | }
124 |
125 | return nil
126 | }
127 | /* vim: set ts=4 sw=4 et smartindent: */
128 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/conf/ndrxconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
12 | 1
13 |
14 |
17 | 5
18 |
19 |
22 | 1
23 |
24 |
27 | 1
28 |
29 |
32 | 5
33 |
34 |
37 |
38 |
42 | 20
43 |
44 |
45 |
50 | Y
51 |
52 |
53 |
54 |
55 | 1
56 | 2
57 |
58 |
61 | 1
62 |
63 |
67 | 2
68 |
69 |
72 | 10
73 |
74 |
79 | 20
80 |
81 |
85 | 3
86 |
87 |
91 | 1
92 |
93 |
94 |
95 |
96 | 2
97 | 2
98 | 1
99 | -e ${NDRX_APPHOME}/log/cconfsrv.log -r
100 |
101 |
102 | 2
103 | 2
104 | 20
105 | -e ${NDRX_APPHOME}/log/tpevsrv.log -r
106 |
107 |
108 | 3
109 | 3
110 | 40
111 | RM1TMQ
112 | -e ${NDRX_APPHOME}/log/tmsrv-rm1.log -r -- -t1 -l${NDRX_APPHOME}/tmlogs/rm1
113 |
114 |
115 | 1
116 | 1
117 | 60
118 | RM1TMQ
119 | -e ${NDRX_APPHOME}/log/tmqueue-rm1.log -r -- -s1
120 |
121 |
122 | 1
123 | 1
124 | 150
125 | -e ${NDRX_APPHOME}/log/tpbridge_2.log -r
126 | -f -n2 -r -i 172.0.0.1 -p 21003 -tA -z30
127 |
128 |
129 | 3
130 | 3
131 | 2000
132 | -e ${NDRX_APPHOME}/log/testsv.log -r
133 |
134 |
135 | 1
136 | 1
137 | 2050
138 | -e ${NDRX_APPHOME}/log/bigmsgsv.log -r
139 |
140 |
141 | 1
142 | 1
143 | 2100
144 | y
145 | -e ${NDRX_APPHOME}/log/restoutsv.log -r
146 | 1
147 |
148 |
149 | 1
150 | 1
151 | 2200
152 | y
153 | -e ${NDRX_APPHOME}/log/restoutsv_bigmsg.log -r
154 | bigmsg
155 |
156 |
157 | 1
158 | 1
159 | 9999
160 | -e ${NDRX_APPHOME}/log/cpmsrv.log -r -- -k3 -i1
161 |
162 |
163 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
--------------------------------------------------------------------------------
/go/src/tcpgatesv/outseq.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Outgiong (Ex->Net) message sequencing
3 | *
4 | * @file outseq.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "sync"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | //ATMI Out message dispatching block
42 | //note that if this is second message in structure then "nr" is invalid
43 | type ATMIOutBlock struct {
44 | id int64
45 | nr int
46 | pool *XATMIPool
47 | ctxData *atmi.TPSRVCTXDATA
48 | buf *atmi.TypedUBF
49 | cd int
50 | }
51 |
52 | var MSeqOutMutex = &sync.Mutex{} //For out message sequencing
53 | var MSeqOutCond = sync.NewCond(MSeqOutMutex)
54 | var MNrMessages = 0 //Number of messages enqueued
55 | var MSeqOutMsgs map[int64][]*ATMIOutBlock
56 |
57 | /*
58 | //Get next work load block
59 | //@param id connect id
60 | //@return Message out or nil (EOF)
61 | func XATMIDispatchCallNext(id int64) *ATMIOutBlock {
62 | //Assume current is done, extract next if have so...
63 | var ret *ATMIOutBlock = nil
64 | //Lock the queues
65 | MSeqOutMutex.Lock()
66 |
67 | MSeqOutMsgs[id] = append(MSeqOutMsgs[id][:0], MSeqOutMsgs[id][1:]...)
68 |
69 | if len(MSeqOutMsgs[id]) == 0 {
70 | MSeqOutMsgs[id] = nil
71 | }
72 |
73 | if nil != MSeqOutMsgs[id] {
74 | ret = MSeqOutMsgs[id][0]
75 | }
76 |
77 | MSeqOutMutex.Unlock()
78 |
79 | return ret
80 | }
81 | */
82 |
83 | //Process messages in loop for given connection id
84 | //@param[in] id connection id
85 | func XATMIDispatchCallRunner(id int64, block *ATMIOutBlock) {
86 |
87 | //var nextBlock *ATMIOutBlock
88 |
89 | nrOurs := block.nr
90 | pool := block.pool //pool shall no change here amog the enqueued objects
91 |
92 | /*
93 | for nextBlock = block; nil != nextBlock; nextBlock = XATMIDispatchCallNext(id) {
94 | XATMIDispatchCall(nextBlock.pool, nrOurs,
95 | nextBlock.ctxData, nextBlock.buf, nextBlock.cd, false)
96 | }
97 | */
98 |
99 | for {
100 | /* read block */
101 | MSeqOutMutex.Lock()
102 |
103 | if len(MSeqOutMsgs[id]) == 0 {
104 | MSeqOutMsgs[id] = nil
105 | MSeqOutMutex.Unlock()
106 | break
107 | }
108 | block = MSeqOutMsgs[id][0]
109 | MSeqOutMutex.Unlock()
110 |
111 | XATMIDispatchCall(block.pool, nrOurs,
112 | block.ctxData, block.buf, block.cd, false)
113 |
114 | /* delete block */
115 | MSeqOutMutex.Lock()
116 | MSeqOutMsgs[id] = MSeqOutMsgs[id][1:]
117 | MNrMessages--
118 | MSeqOutCond.Signal()
119 | MSeqOutMutex.Unlock()
120 | }
121 |
122 | //Free up the chan
123 | pool.freechan <- nrOurs
124 | }
125 |
126 | //Sequenced message dispatching
127 | //@param id connection id, either compiled or simple, up to user
128 | //@param pool XATMI pool
129 | //@param nr thread number in pool
130 | //@param ctxData context data
131 | //@param buf call buffer
132 | //@param cd call descriptor (XATMI)
133 | func XATMIDispatchCallSeq(id int64, pool *XATMIPool, nr int, ctxData *atmi.TPSRVCTXDATA,
134 | buf *atmi.TypedUBF, cd int) {
135 |
136 | //Lock the queues
137 | MSeqOutMutex.Lock()
138 |
139 | //let threads to complete.
140 | if MNrMessages >= MWorkersOut {
141 | //wait on cond..
142 | MSeqOutCond.Wait()
143 | }
144 |
145 | startNew := false
146 |
147 | block := ATMIOutBlock{id: id, pool: pool, nr: nr, ctxData: ctxData, buf: buf, cd: cd}
148 |
149 | if nil == MSeqOutMsgs[id] {
150 | startNew = true
151 | }
152 | MSeqOutMsgs[id] = append(MSeqOutMsgs[id], &block)
153 |
154 | MNrMessages++
155 | if startNew {
156 | go XATMIDispatchCallRunner(id, &block)
157 | } else {
158 | //We shall release the channel as runner will work with his chan
159 | pool.freechan <- nr
160 | }
161 |
162 | MSeqOutMutex.Unlock()
163 |
164 | }
165 |
166 | /* vim: set ts=4 sw=4 et smartindent: */
167 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/fileupload.go:
--------------------------------------------------------------------------------
1 | /**
2 | * File upload handler
3 | */
4 | package main
5 |
6 | import (
7 | "os/exec"
8 | "strings"
9 | u "ubftab"
10 |
11 | atmi "github.com/endurox-dev/endurox-go"
12 | )
13 |
14 | const (
15 | SUCCEED = 0
16 | FAIL = -1
17 | )
18 |
19 | //Check if the failure is due to internal workings
20 | //Check the error code that it matches
21 | //If so return message "DIS"
22 | func UPLDERR(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
23 |
24 | ret := SUCCEED
25 |
26 | //Get UBF Handler
27 | ub, _ := ac.CastToUBF(&svc.Data)
28 | ac.TpLogSetReqFile(ub, "", "")
29 | //Return to the caller
30 | defer func() {
31 |
32 | ub.TpLogPrintUBF(atmi.LOG_DEBUG, "Returning:")
33 |
34 | ac.TpLogCloseReqFile()
35 | if SUCCEED == ret {
36 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
37 | } else {
38 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
39 | }
40 | }()
41 |
42 | tperrno, _ := ub.BGetInt(u.EX_IF_ECODE, 0)
43 | tperrsrc, _ := ub.BGetString(u.EX_IF_ERRSRC, 0)
44 | tpstrerror, _ := ub.BGetString(u.EX_IF_EMSG, 0)
45 |
46 | ac.TpLogDebug("Got error tperrno: %d src: %s msg: %s", tperrno, tperrsrc, tpstrerror)
47 |
48 | if tperrno == atmi.TPEOS && tperrsrc == "R" {
49 | //This is OK condition, set the message
50 | ub.BChg(u.EX_IF_RSPDATA, 0, "DISK FAILURE")
51 | } else {
52 | ub.BChg(u.EX_IF_RSPDATA, 0, "OTHER FAILURE: "+tperrsrc)
53 | }
54 |
55 | //Set return code OK
56 |
57 | ub.BChg(u.EX_NETRCODE, 0, "200")
58 |
59 | }
60 |
61 | //This will receive the files on disk, perform the checksum
62 | //And will return \n on reply body
63 | func FILEUPLOAD(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
64 |
65 | ret := SUCCEED
66 | var reply string
67 | //Get UBF Handler
68 | ub, _ := ac.CastToUBF(&svc.Data)
69 |
70 | ac.TpLogSetReqFile(ub, "", "")
71 |
72 | //Return to the caller
73 | defer func() {
74 |
75 | ub.TpLogPrintUBF(atmi.LOG_DEBUG, "Response buf:")
76 | ac.TpLogCloseReqFile()
77 | if SUCCEED == ret {
78 | ac.TpReturn(atmi.TPSUCCESS, 0, ub, 0)
79 | } else {
80 | ac.TpReturn(atmi.TPFAIL, 0, ub, 0)
81 | }
82 | }()
83 |
84 | //Print the buffer to stdout
85 | ub.TpLogPrintUBF(atmi.LOG_DEBUG, "Incoming request:")
86 |
87 | //Loop over the buffer... we will mark file No 1.ac
88 |
89 | occs, errU := ub.BOccur(u.EX_IF_REQFILEDISK)
90 |
91 | if nil != errU {
92 | ac.TpLogError("TESTERROR: Error reading EX_IF_REQFILEDISK")
93 | ret = FAIL
94 | return
95 | }
96 |
97 | if occs < 3 {
98 | ac.TpLogError("TESTERROR: Expected atleast 3 occs (got %d)", occs)
99 | ret = FAIL
100 | return
101 | }
102 |
103 | //Resize buffer, to have some more space
104 | used, _ := ub.BUsed()
105 | if err := ub.TpRealloc(used + 1024); err != nil {
106 | ac.TpLogError("TpRealloc() Got error: %d:[%s]\n", err.Code(), err.Message())
107 | ret = FAIL
108 | return
109 | }
110 |
111 | //If occs==3, the we leave first file on disk
112 | //In other cases all files from disk must be deleted
113 |
114 | //Process each of the files...
115 | for i := 0; i < occs; i++ {
116 |
117 | if 3 == occs {
118 | //Set the keep flag
119 | if 2 == i {
120 | ub.BChg(u.EX_IF_RSPFILEACTION, i, "K")
121 | } else {
122 | ub.BChg(u.EX_IF_RSPFILEACTION, i, "D")
123 | }
124 | } else {
125 | //Having other occs, just delete (default)
126 | }
127 |
128 | //Get the file on disk
129 | diskname, errU := ub.BGetString(u.EX_IF_REQFILEDISK, i)
130 | if nil != errU {
131 | ac.TpLogError("Failed to get EX_IF_REQFILEDISK[%d]: %s", i, errU.Error())
132 | ret = FAIL
133 | return
134 | }
135 | ac.TpLogInfo("File name on disk is: [%s]", diskname)
136 |
137 | //Get the file name at user side
138 | fname, errU := ub.BGetString(u.EX_IF_REQFILENAME, i)
139 | if nil != errU {
140 | ac.TpLogError("Failed to get EX_IF_REQFILENAME[%d]: %s", i, errU.Error())
141 | ret = FAIL
142 | return
143 | }
144 | ac.TpLogInfo("Form file name (user side): [%s]", fname)
145 |
146 | //Get the mime
147 | mime, errU := ub.BGetString(u.EX_IF_REQFILEMIME, i)
148 | if nil != errU {
149 | ac.TpLogError("Failed to get EX_IF_REQFILEMIME[%d]: %s", i, errU.Error())
150 | ret = FAIL
151 | return
152 | }
153 | ac.TpLogInfo("Mime: [%s]", mime)
154 |
155 | //Get the form field name
156 | formname, errU := ub.BGetString(u.EX_IF_REQFILEFORM, i)
157 | if nil != errU {
158 | ac.TpLogError("Failed to get EX_IF_REQFILEFORM[%d]: %s", i, errU.Error())
159 | ret = FAIL
160 | return
161 | }
162 | ac.TpLogInfo("Form field: [%s]", formname)
163 |
164 | //Disk file name shall be different that user
165 | //this is nature of the test
166 | if diskname == fname {
167 | ac.TpLogError("Disk file name [%s] shall not match the logical upload file name [%s] at occ %d",
168 | diskname, fname, i)
169 | ret = FAIL
170 | return
171 | }
172 |
173 | cmd := exec.Command("cksum", diskname)
174 | out, err := cmd.Output()
175 |
176 | if err != nil {
177 | ac.TpLogError("Failed to get checksum for [%s]: %s", diskname, err.Error())
178 | ret = FAIL
179 | return
180 | }
181 |
182 | strout := strings.Replace(string(out), diskname, fname, -1)
183 | reply += (strout + "\n")
184 |
185 | }
186 |
187 | //Get the chekcsum
188 | ac.TpLogInfo("Reply: [%s]", reply)
189 | //Load the reply
190 | if errU := ub.BChg(u.EX_IF_RSPDATA, 0, reply); nil != errU {
191 | ac.TpLogError("TpRealloc() Got error: %d:[%s]", errU.Code(), errU.Message())
192 | ret = FAIL
193 | return
194 | }
195 |
196 | return
197 | }
198 |
--------------------------------------------------------------------------------
/tests/01_restin/src/testsv/viewsv.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import atmi "github.com/endurox-dev/endurox-go"
4 |
5 | //VIEW service
6 | //@param ac ATMI Context
7 | //@param svc Service call information
8 | func VIEWSV1(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
9 |
10 | ret := FAIL
11 |
12 | //Get UBF Handler
13 | v, _ := ac.CastToVIEW(&svc.Data)
14 |
15 | //Return to the caller
16 | defer func() {
17 | if SUCCEED == ret {
18 | ac.TpReturn(atmi.TPSUCCESS, 0, v, 0)
19 | } else {
20 | ac.TpReturn(atmi.TPFAIL, 0, v, 0)
21 | }
22 | }()
23 |
24 | //Test data received
25 | tshort1, errU := v.BVGetInt16("tshort1", 0, 0)
26 | ac.TpAssertEqualPanic(errU, nil, "tshort1=> must be nil")
27 | ac.TpAssertEqualPanic(tshort1, 5, "tshort1 value")
28 |
29 | tlong1, errU := v.BVGetInt64("tlong1", 0, 0)
30 | ac.TpAssertEqualPanic(errU, nil, "tlong1=> must be nil")
31 | ac.TpAssertEqualPanic(tlong1, 77777, "tlong1 value")
32 |
33 | tstring1, errU := v.BVGetString("tstring1", 1, 0)
34 | ac.TpAssertEqualPanic(errU, nil, "tstring1=> must be nil")
35 | ac.TpAssertEqualPanic(tstring1, "INCOMING TEST", "tstring1 value")
36 |
37 | //Set response data
38 |
39 | if errU = v.BVChg("tshort1", 0, 8); nil != errU {
40 | ac.TpLogError("Failed to set tshort1: %s", errU.Error())
41 | return
42 | }
43 |
44 | if errU = v.BVChg("tlong1", 0, 11111); nil != errU {
45 | ac.TpLogError("Failed to set tlong1: %s", errU.Error())
46 | return
47 | }
48 |
49 | if errU = v.BVChg("tstring1", 0, "HELLO RESPONSE"); nil != errU {
50 | ac.TpLogError("Failed to set tstring1: %s", errU.Error())
51 | return
52 | }
53 |
54 | ret = SUCCEED
55 |
56 | return
57 | }
58 |
59 | //VIEW service - return different view W/O RSP
60 | //@param ac ATMI Context
61 | //@param svc Service call information
62 | func VIEWSV2(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
63 |
64 | ret := SUCCEED
65 |
66 | //Get UBF Handler
67 | v, _ := ac.CastToVIEW(&svc.Data)
68 |
69 | //Return to the caller
70 | defer func() {
71 | if SUCCEED == ret {
72 | ac.TpReturn(atmi.TPSUCCESS, 0, v, 0)
73 | } else {
74 | ac.TpReturn(atmi.TPFAIL, 0, v, 0)
75 | }
76 | }()
77 |
78 | //Test data received
79 | tshort1, errU := v.BVGetInt16("tshort1", 0, 0)
80 | ac.TpAssertEqualPanic(errU, nil, "tshort1=> must be nil")
81 |
82 | tlong1, errU := v.BVGetInt64("tlong1", 0, 0)
83 | ac.TpAssertEqualPanic(errU, nil, "tlong1=> must be nil")
84 |
85 | tstring1, errU := v.BVGetString("tstring1", 1, 0)
86 | ac.TpAssertEqualPanic(errU, nil, "tstring1=> must be nil")
87 |
88 | v2, errA := ac.NewVIEW("REQUEST2", 0)
89 | ac.TpAssertEqualPanic(errA, nil, "Request2: errA must be nil")
90 |
91 | errU = v2.BVChg("tshort2", 0, tshort1)
92 | ac.TpAssertEqualPanic(errU, nil, "Request2: tshort2")
93 |
94 | errU = v2.BVChg("tlong2", 0, tlong1)
95 | ac.TpAssertEqualPanic(errU, nil, "Request2: tlong2")
96 |
97 | errU = v2.BVChg("tstring2", 0, tstring1)
98 | ac.TpAssertEqualPanic(errU, nil, "Request2: tstring2")
99 |
100 | v = v2
101 |
102 | return
103 | }
104 |
105 | //VIEW service - Failure service, with different buffer
106 | //@param ac ATMI Context
107 | //@param svc Service call information
108 | func VIEWFAIL(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
109 |
110 | //Get UBF Handler
111 | v, _ := ac.CastToVIEW(&svc.Data)
112 |
113 | //Return to the caller
114 | defer func() {
115 | ac.TpReturn(atmi.TPFAIL, 0, v, 0)
116 | }()
117 |
118 | //Test data received
119 | tshort1, errU := v.BVGetInt16("tshort1", 0, 0)
120 | ac.TpAssertEqualPanic(errU, nil, "tshort1=> must be nil")
121 |
122 | tlong1, errU := v.BVGetInt64("tlong1", 0, 0)
123 | ac.TpAssertEqualPanic(errU, nil, "tlong1=> must be nil")
124 |
125 | tstring1, errU := v.BVGetString("tstring1", 1, 0)
126 | ac.TpAssertEqualPanic(errU, nil, "tstring1=> must be nil")
127 |
128 | v2, errA := ac.NewVIEW("REQUEST2", 0)
129 | ac.TpAssertEqualPanic(errA, nil, "Request2: errA must be nil")
130 |
131 | errU = v2.BVChg("tshort2", 0, tshort1)
132 | ac.TpAssertEqualPanic(errU, nil, "Request2: tshort2")
133 |
134 | errU = v2.BVChg("tlong2", 0, tlong1)
135 | ac.TpAssertEqualPanic(errU, nil, "Request2: tlong2")
136 |
137 | errU = v2.BVChg("tstring2", 0, tstring1)
138 | ac.TpAssertEqualPanic(errU, nil, "Request2: tstring2")
139 |
140 | v = v2
141 |
142 | return
143 | }
144 |
145 | //VIEW service, FAIL2
146 | //@param ac ATMI Context
147 | //@param svc Service call information
148 | func VIEWFAIL2(ac *atmi.ATMICtx, svc *atmi.TPSVCINFO) {
149 |
150 | //Get UBF Handler
151 | v, _ := ac.CastToVIEW(&svc.Data)
152 |
153 | //Return to the caller
154 | defer func() {
155 | ac.TpReturn(atmi.TPFAIL, 0, v, 0)
156 | }()
157 |
158 | //Test data received
159 | tshort1, errU := v.BVGetInt16("tshort1", 0, 0)
160 | ac.TpAssertEqualPanic(errU, nil, "tshort1=> must be nil")
161 | ac.TpAssertEqualPanic(tshort1, 5, "tshort1 value")
162 |
163 | tlong1, errU := v.BVGetInt64("tlong1", 0, 0)
164 | ac.TpAssertEqualPanic(errU, nil, "tlong1=> must be nil")
165 | ac.TpAssertEqualPanic(tlong1, 77777, "tlong1 value")
166 |
167 | tstring1, errU := v.BVGetString("tstring1", 1, 0)
168 | ac.TpAssertEqualPanic(errU, nil, "tstring1=> must be nil")
169 | ac.TpAssertEqualPanic(tstring1, "INCOMING TEST", "tstring1 value")
170 |
171 | //Set response data
172 |
173 | if errU = v.BVChg("tshort1", 0, 8); nil != errU {
174 | ac.TpLogError("Failed to set tshort1: %s", errU.Error())
175 | return
176 | }
177 |
178 | if errU = v.BVChg("tlong1", 0, 11111); nil != errU {
179 | ac.TpLogError("Failed to set tlong1: %s", errU.Error())
180 | return
181 | }
182 |
183 | if errU = v.BVChg("tstring1", 0, "HELLO RESPONSE"); nil != errU {
184 | ac.TpLogError("Failed to set tstring1: %s", errU.Error())
185 | return
186 | }
187 |
188 | return
189 | }
190 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/conf/restin.ini:
--------------------------------------------------------------------------------
1 | #
2 | # JSON UBF test, sync
3 | #
4 | [@restin/1]
5 | debug= ndrx=3 tp=3 ubf=0 iflags=detailed threaded=y
6 | port=8080
7 | ip=0.0.0.0
8 | gencore=1
9 | #
10 | # Defaults: conv=json2ubf
11 | # async - call service in async way, if submitted ok, just reply back with ok
12 | #
13 | # Hmm we could use same format for definding defaults...
14 | defaults={"errors":"http"
15 | ,"reqlogsvc": "GETFILE"
16 | ,"noreqfilersp": true
17 | }
18 |
19 | ################################################################################
20 | # JSON2UBF test cases, JSON2UBF error codes
21 | ################################################################################
22 | /jubfjue_ok={"svc":"DATASV1", "notime":false, "conv":"json2ubf", "errors":"json2ubf", "async":false}
23 |
24 | # This will return server error
25 | /jubfjue_fail={"svc":"FAILSV1", "notime":false, "conv":"json2ubf", "errors":"json2ubf", "async":false}
26 |
27 | # Time-out
28 | /jubfjue_tout={"svc":"LONGOP", "notime":false, "conv":"json2ubf", "errors":"json2ubf", "async":false}
29 | ################################################################################
30 | # JSON2UBF, http error codes
31 | ################################################################################
32 | /jubfhte_ok={"svc":"DATASV1", "notime":false, "conv":"json2ubf", "errors":"http", "async":false}
33 |
34 | # This will return server error
35 | /jubfhte_fail={"svc":"FAILSV1", "notime":false, "conv":"json2ubf", "errors":"http", "async":false}
36 |
37 | # Time-out
38 | /jubfhte_tout={"svc":"LONGOP", "notime":false, "conv":"json2ubf", "errors":"http", "async":false}
39 | ################################################################################
40 |
41 | ################################################################################
42 | # STRING, text error codes
43 | ################################################################################
44 | /textte_ok={"svc":"TEXTSV", "notime":false, "conv":"text", "errors":"text", "async":false}
45 |
46 | # This will return server error
47 | /textte_fail={"svc":"FAILSV1", "notime":false, "conv":"text", "errors":"text", "async":false}
48 | ################################################################################
49 | # JSON, json error fields
50 | ################################################################################
51 | # Test JSON buffer format
52 | /jsonje_ok={"svc":"JSONSV", "conv":"json", "errors":"json"}
53 | # Test JSON buffer format, no error fields:
54 | /jsonje_okns={"svc":"JSONSV", "conv":"json", "errors":"json", "errfmt_json_onsucc":false}
55 | # Asyn json
56 | /jsonje_okasync={"svc":"JSONSV", "conv":"json", "errors":"json", "async":true}
57 | # Test JSON errors
58 | /jsonje_fail={
59 | "svc":"FAILSV1"
60 | ,"conv":"json"
61 | ,"errors":"json"
62 | ,"errfmt_json_msg":"\"message\":\"%s\""
63 | ,"errfmt_json_code":"\"code\":%d"
64 | }
65 | ################################################################################
66 | # Carray buffer, ok
67 | ################################################################################
68 | /rawte_ok={"svc":"BINARYSV", "conv":"raw", "errors":"text", "async":false}
69 | # Carray buffer, fail
70 | /rawte_fail={"svc":"FAILSV1", "conv":"raw", "errors":"text", "async":false}
71 | ################################################################################
72 | # ECHO, JSON2UBF
73 | ################################################################################
74 | /echo_json2ubf={"notime":false, "errors":"json2ubf", "echo":true}
75 | ################################################################################
76 | # ECHO, JSON
77 | ################################################################################
78 | /echo_json={"notime":false, "errors":"json", "echo":true}
79 | # Have some test for JSON http errors:
80 | /dep_jsonhte={"svc":"JSONSV", "conv":"json", "errors":"http"}
81 | ################################################################################
82 | # ECHO, STRING
83 | ################################################################################
84 | /echo_string={"notime":false, "conv": "text", "errors":"text", "echo":true}
85 | # Have some test for JSON http errors:
86 | /dep_stringhte={"svc":"TEXTSV", "conv":"text", "errors":"http"}
87 | ################################################################################
88 | # ECHO, RAW
89 | ################################################################################
90 | /echo_raw={"svc":"BINARYSV", "conv":"raw", "errors":"text", "async":false, "echo":true}
91 | /dep_rawhte={"svc":"BINARYSV", "conv":"raw", "errors":"http", "async":false}
92 |
93 | ################################################################################
94 | # VIEW tests
95 | ################################################################################
96 |
97 | #
98 | # Response with response view, ubf2view errors
99 | #
100 | /viewerr/ok={"svc":"VIEWSV1", "conv":"json2view", "errors":"json2view",
101 | "errfmt_view_msg":"rspmessage", "errfmt_view_code":"rspcode", "errfmt_view_onsucc":true,
102 | "errfmt_view_rsp":"RSPV"}
103 |
104 | # Failed service with ubf2view
105 | /viewerr/fail={"svc":"VIEWFAIL2"
106 | , "conv":"json2view"
107 | , "errors":"json2view"
108 | , "errfmt_view_msg":"rspmessage"
109 | , "errfmt_view_code":"rspcode"
110 | , "errfmt_view_onsucc":false
111 | , "errfmt_view_rsp":"RSPV"}
112 |
113 | # Time-out
114 | /viewerr/tout={"svc":"LONGOP2"
115 | , "notime":false
116 | , "conv":"json2view"
117 | , "errors":"json2view"
118 | , "errfmt_view_msg":"rspmessage"
119 | , "errfmt_view_code":"rspcode"
120 | , "errfmt_view_onsucc":false
121 | , "errfmt_view_rsp":"RSPV"}
122 |
123 | # View http errors, OK
124 | /viewhttp/ok={"svc":"VIEWSV1", "conv":"json2view", "errors":"http"}
125 |
126 | # View http errors, FAIL
127 | /viewhttp/fail={"svc":"VIEWFAIL2", "conv":"json2view", "errors":"http"}
128 |
129 | # Echo test for view
130 | /echo_json2view={"notime":false
131 | , "conv":"json2view"
132 | , "errors":"json2view"
133 | , "errfmt_view_onsucc":true
134 | , "errfmt_view_msg":"rspmessage"
135 | , "errfmt_view_code":"rspcode"
136 | , "echo":true}
137 |
138 | #
139 | # TLS tests
140 | #
141 | [@restin/1/TLS]
142 | tls_enable=1
143 | tls_cert_file=${NDRX_APPHOME}/conf/localhost.crt
144 | tls_key_file=${NDRX_APPHOME}/conf/localhost.key
145 |
146 |
147 | #
148 | # JSON UBF test, sync
149 | #
150 | [@restin/bigmsg]
151 | debug= ndrx=4 tp=4 ubf=0 iflags=detailed threaded=y
152 | port=8181
153 | ip=0.0.0.0
154 | gencore=1
155 | #
156 | # Defaults: conv=json2ubf
157 | # async - call service in async way, if submitted ok, just reply back with ok
158 | #
159 | # Hmm we could use same format for definding defaults...
160 | defaults={"errors":"http"
161 | ,"reqlogsvc": "GETFILE"
162 | ,"noreqfilersp": true
163 | }
164 |
165 | # Test case for big messages (1M)
166 | /bigmsg={"svc":"BIGMSG", "notime":false, "conv":"json2ubf", "errors":"json2ubf", "async":false}
167 |
168 |
--------------------------------------------------------------------------------
/go/src/restincl/viewsupp.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief View support
3 | *
4 | * @file viewsupp.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "fmt"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | //Install error code in the view, Note max allowed error message size is 1024 bytes
42 | //including EOS
43 | //@param buf VIEW buffer
44 | //@param code error code to install
45 | //@param msg error message to install
46 | //@return nil on OK, UBF error on failure
47 | func VIEWInstallError(buf *atmi.TypedVIEW, view string, view_code_fld string,
48 | code int, view_msg_fld string, msg string) atmi.UBFError {
49 |
50 | //Check the length of the message field
51 |
52 | _, _, _, dim_size, _, errU := buf.BVOccur(view_msg_fld)
53 |
54 | if nil != errU {
55 | buf.Buf.Ctx.TpLogError("Failed to get %s.%s infos: %s",
56 | view, view_msg_fld, errU.Error())
57 | return errU
58 | }
59 |
60 | buf.Buf.Ctx.TpLogInfo("message field dim size: %d", dim_size)
61 | //Conver message to bytes:
62 |
63 | byteStr := []byte(msg)
64 |
65 | //+1 for C EOS
66 | if int64(len(byteStr)+1) > dim_size {
67 | byteStr = byteStr[0 : dim_size-1] //1 for EOS
68 | }
69 |
70 | if errU := buf.BVChg(view_code_fld, 0, code); nil != errU {
71 | buf.Buf.Ctx.TpLogError("Failed to test/set code in resposne %s.[%s] to [%d]: %s",
72 | view, view_code_fld, code, errU.Error())
73 | return errU
74 | }
75 |
76 | if errU := buf.BVChg(view_msg_fld, 0, byteStr); nil != errU {
77 | buf.Buf.Ctx.TpLogError("Failed to test/set message in resposne %s.[%s] to [%d]: %s",
78 | view, view_msg_fld, string(byteStr), errU.Error())
79 | return errU
80 | }
81 |
82 | return nil
83 | }
84 |
85 | //Validate view service settings
86 | //@param ac ATMI context
87 | //@param svc Service map
88 | //@return error or nil
89 | func VIEWSvcValidateSettings(ac *atmi.ATMICtx, svc *ServiceMap) error {
90 |
91 | //Set not NULL flag
92 | if svc.View_notnull {
93 | ac.TpLogInfo("VIEWs in responses will contain non NULL fields only " +
94 | "(according to view file)")
95 | svc.View_flags |= atmi.BVACCESS_NOTNULL
96 | }
97 |
98 | if svc.Errors_int != ERRORS_JSON2VIEW {
99 | return nil //Nothing to validate
100 | }
101 |
102 | //For async calls we need response object
103 | if svc.Asynccall && !svc.Asyncecho && svc.Errfmt_view_rsp == "" {
104 | err := fmt.Errorf("Tag 'errfmt_view_rsp' must set in case if 'async' " +
105 | "is set and 'asyncecho' is not set")
106 | ac.TpLogError(err.Error())
107 | return err
108 | }
109 |
110 | //Error fields must be present
111 | ac.TpLogInfo("Errfmt_view_msg=[%s] Errfmt_view_code=[%s]",
112 | svc.Errfmt_view_msg, svc.Errfmt_view_code)
113 | if "" == svc.Errfmt_view_msg || "" == svc.Errfmt_view_code {
114 | err := fmt.Errorf("Tags 'errfmt_view_code' and 'errfmt_view_msg' " +
115 | "must be present in case of 'json2view' errors")
116 | ac.TpLogError(err.Error())
117 | return err
118 | }
119 |
120 | //If response goes first, the response view must be set
121 | if svc.Errfmt_view_rsp_first && "" == svc.Errfmt_view_rsp {
122 | err := fmt.Errorf("If responding with response view first " +
123 | "('errfmt_view_rsp_first' true), tag 'errfmt_view_rsp' must be set")
124 | ac.TpLogError(err.Error())
125 | return err
126 | }
127 |
128 | //Test the response object if have one.
129 |
130 | ac.TpLogInfo("Testing view: %s setting code in %s and message in %s",
131 | svc.Errfmt_view_rsp, svc.Errfmt_view_code,
132 | svc.Errfmt_view_msg)
133 |
134 | if svc.Errfmt_view_rsp != "" {
135 | buf, errA := ac.NewVIEW(svc.Errfmt_view_rsp, 0)
136 |
137 | if nil != errA {
138 | err := fmt.Errorf("Failed to alloc VIEW/[%s]: %s",
139 | svc.Errfmt_view_rsp, errA.Error())
140 | ac.TpLogError(err.Error())
141 | return err
142 | }
143 |
144 | errA = VIEWInstallError(buf, svc.Errfmt_view_rsp,
145 | svc.Errfmt_view_code, 0, svc.Errfmt_view_msg,
146 | "SUCCEED")
147 | }
148 |
149 | return nil
150 | }
151 |
152 | //Generate response from view configured
153 | //@param ac ATMI Context
154 | //@param svc Servic map
155 | //@param atmiErr ATMI error to put in response
156 | //@return In case of error return []
157 | func VIEWGenDefaultResponse(ac *atmi.ATMICtx, svc *ServiceMap, atmiErr atmi.ATMIError) []byte {
158 | //In this case response VIEW buffer must be set.
159 |
160 | if nil == atmiErr {
161 | atmiErr = atmi.NewCustomATMIError(atmi.TPMINVAL, "SUCCEED")
162 | }
163 | bufv, errA := ac.NewVIEW(svc.Errfmt_view_rsp, 0)
164 |
165 | if nil != errA {
166 | ac.TpLogError("Failed to alloc VIEW/[%s] - dropping response: %s",
167 | svc.Errfmt_view_rsp, errA.Error())
168 | ac.UserLog("Failed to alloc VIEW/[%s] - dropping response: %s",
169 | svc.Errfmt_view_rsp, errA.Error())
170 | return []byte("{}")
171 | }
172 |
173 | if errU := VIEWInstallError(bufv, svc.Errfmt_view_rsp,
174 | svc.Errfmt_view_code, atmiErr.Code(), svc.Errfmt_view_msg,
175 | atmiErr.Message()); nil != errU {
176 |
177 | ac.TpLogError("Failed to set viewe response - dropping: %s",
178 | atmiErr.Message())
179 |
180 | ac.UserLog("Failed to set view response - dropping: %s",
181 | atmiErr.Message())
182 |
183 | return []byte("{}")
184 |
185 | }
186 |
187 | //The resposne view contains all field no matter of the non-null setting
188 | ret, err1 := bufv.TpVIEWToJSON(0)
189 |
190 | if nil == err1 {
191 | //Generate the resposne buffer...
192 | rsp := []byte(ret)
193 |
194 | return rsp
195 |
196 | } else {
197 | ac.TpLogError("Failed to convert VIEW to JSON - dropping response: %s",
198 | err1.Error())
199 |
200 | ac.UserLog("Failed to convert VIEW to JSON - dropping response: %s",
201 | err1.Error())
202 |
203 | return nil
204 | }
205 | }
206 | /* vim: set ts=4 sw=4 et smartindent: */
207 |
--------------------------------------------------------------------------------
/go/src/restincl/fileupload.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief File upload handler (multi-part form)
3 | *
4 | * @file fileupload.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "fmt"
37 | "io"
38 | "io/ioutil"
39 | "mime/multipart"
40 | "net/http"
41 | "os"
42 | "strings"
43 | "ubftab"
44 |
45 | atmi "github.com/endurox-dev/endurox-go"
46 | )
47 |
48 | const (
49 | FILES_FLAG_KEEP = "K" //Keep the files after the upload service finish
50 | FILES_FLAG_DELETE = "D" //Delete the file (RFU)
51 | )
52 |
53 | //This is used to strack
54 | //additional request details
55 | //Including list of files uploaded
56 | type RequestContext struct {
57 | errSrc string
58 | fileList []string
59 | }
60 |
61 | //Prepare file upload (request part, download & prepare the UBF buffer)
62 | //@param ac ATMI Context
63 | //@param bufu ATMI buffer (must be UBF) for EXT processing
64 | //@param svc Target service
65 | //@param req HTTP request obj
66 | //@param rctx request context attributes
67 | //@return ATMI error or nil
68 | func handleFileUploadReq(ac *atmi.ATMICtx, bufu *atmi.TypedUBF, svc *ServiceMap,
69 | r *http.Request, rctx *RequestContext) atmi.ATMIError {
70 |
71 | var n int
72 | var err error
73 | var occ = 0
74 | // define pointers for the multipart reader and its parts
75 | var mr *multipart.Reader
76 | var part *multipart.Part
77 |
78 | ac.TpLogInfo("Receiving file upload...")
79 |
80 | if mr, err = r.MultipartReader(); err != nil {
81 |
82 | ac.TpLogError("Failed to open multi-part reader: %s", err.Error())
83 | return atmi.NewCustomATMIError(atmi.TPESYSTEM, fmt.Sprintf(
84 | "Failed to open multi-part reader: %s", err.Error()))
85 | }
86 |
87 | // buffer to be used for reading bytes from files
88 | chunk := make([]byte, 4096)
89 |
90 | for {
91 | var tempfile *os.File
92 | var filesize int
93 | var uploaded bool
94 |
95 | if part, err = mr.NextPart(); err != nil {
96 | if err != io.EOF {
97 | ac.TpLogError("Error while fetching next part: %s", err.Error())
98 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
99 | fmt.Sprintf("Error while fetching next part: %s", err.Error()))
100 |
101 | } else {
102 | ac.TpLogInfo("Multipart upload OK")
103 | return nil
104 | }
105 | }
106 |
107 | ac.TpLogDebug("Uploaded filename occ=%d: %s", occ, part.FileName())
108 | ac.TpLogDebug("Uploaded mimetype occ=%d: %s", occ, part.Header)
109 |
110 | //Add the file names to the buffer
111 | if errU := bufu.BAdd(ubftab.EX_IF_REQFILENAME, part.FileName()); nil != errU {
112 | ac.TpLogError("Failed to add EX_IF_REQFILENAME[%d]: %s", occ, errU.Error())
113 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
114 | fmt.Sprintf("Failed to add EX_IF_REQFILENAME[%d]: %s", occ, errU.Error()))
115 | }
116 |
117 | if errU := bufu.BAdd(ubftab.EX_IF_REQFILEFORM, part.FormName()); nil != errU {
118 | ac.TpLogError("Failed to add EX_IF_REQFILEFORM[%d]: %s", occ, errU.Error())
119 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
120 | fmt.Sprintf("Failed to add EX_IF_REQFILEFORM[%d]: %s", occ, errU.Error()))
121 | }
122 |
123 | if errU := bufu.BAdd(ubftab.EX_IF_REQFILEMIME, part.Header.Get("Content-Type")); nil != errU {
124 | ac.TpLogError("Failed to add EX_IF_REQFILEMIME[%d]: %s", occ, errU.Error())
125 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
126 | fmt.Sprintf("Failed to add EX_IF_REQFILEMIME[%d]: %s", occ, errU.Error()))
127 | }
128 |
129 | //Add the file name to received rctx
130 |
131 | tempfile, err = ioutil.TempFile(svc.Tempdir, fmt.Sprintf("%s-%s", progsection, M_cctag))
132 | if err != nil {
133 | return atmi.NewCustomATMIError(atmi.TPEOS,
134 | fmt.Sprintf("Error while creating temp file: %s", err.Error()))
135 | }
136 |
137 | ac.TpLogInfo("Got file name for file occ %d: %s", occ, tempfile.Name())
138 | rctx.fileList = append(rctx.fileList, tempfile.Name())
139 |
140 | if errU := bufu.BAdd(ubftab.EX_IF_REQFILEDISK, tempfile.Name()); nil != errU {
141 | ac.TpLogError("Failed to add EX_IF_REQFILEDISK[%d]: %s", occ, errU.Error())
142 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
143 | fmt.Sprintf("Failed to add EX_IF_REQFILEDISK[%d]: %s", occ, errU.Error()))
144 | }
145 |
146 | defer tempfile.Close()
147 |
148 | // Read all parts of the file & write off to disk...
149 | for !uploaded {
150 | if n, err = part.Read(chunk); err != nil {
151 | if err != io.EOF {
152 | ac.TpLogError("Error reading chunk: %s", err.Error())
153 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
154 | fmt.Sprintf("Error reading chunk: %s", err.Error()))
155 | }
156 | uploaded = true
157 | }
158 |
159 | if n, err = tempfile.Write(chunk[:n]); err != nil {
160 | ac.TpLogError("Error writing chunk to [%s]: %s", tempfile.Name(), err.Error())
161 | return atmi.NewCustomATMIError(atmi.TPEOS,
162 | fmt.Sprintf("Error writing chunk [%s] to: %s", tempfile.Name(), err.Error()))
163 | }
164 | filesize += n
165 | }
166 |
167 | ac.TpLogInfo("Uploaded file [%s] size: %d bytes", tempfile.Name(), filesize)
168 |
169 | occ++
170 | }
171 |
172 | }
173 |
174 | //Handle response after the file processed
175 | //@param ac ATMI Context
176 | //@param ubfu UBF buffer used for request handling
177 | //@param service definition
178 | //@param rctx request boject
179 | //@return ATMI error if any
180 | func handleFileUploadRsp(ac *atmi.ATMICtx, bufu *atmi.TypedUBF, svc *ServiceMap,
181 | rctx *RequestContext) atmi.ATMIError {
182 |
183 | for i, s := range rctx.fileList {
184 |
185 | //Check the action by index
186 |
187 | action, _ := bufu.BGetString(ubftab.EX_IF_RSPFILEACTION, i)
188 |
189 | if strings.Contains(action, FILES_FLAG_KEEP) {
190 | ac.TpLogInfo("Keeping file [%s] (occ %d)", s, i)
191 | } else {
192 | ac.TpLogInfo("Removing file [%s] (occ %d)", s, i)
193 | os.Remove(s)
194 | }
195 | }
196 |
197 | return nil
198 | }
199 |
200 | /* vim: set ts=4 sw=4 et smartindent: */
201 |
--------------------------------------------------------------------------------
/tests/03_restout/runtime/conf/restout.ini:
--------------------------------------------------------------------------------
1 | # additional view settings...
2 | [@global]
3 | VIEWDIR=${NDRX_APPHOME}/viewdir
4 | VIEWFILES=restin.V
5 |
6 | [@restout/1]
7 | # Enduro/X debug string setup
8 | debug = tp=3 ndrx=3 iflags=detailed file= threaded=y
9 | gencore=1
10 | workers=5
11 | scan_time=7
12 | #
13 | # Defaults: conv=json2ubf
14 | # async - call service in async way, if submitted ok, just reply back with ok
15 | #
16 |
17 | # MOVED DOWN FOR SECON-PASS CONFIG TEST
18 | #defaults={"urlbase":"https://localhost:8080"
19 | # ,"errors":"http"
20 | # ,"noreqfilersp": true
21 | # ,"sslinsecure": true
22 | # }
23 |
24 | ################################################################################
25 | # JSON2UBF test case - jue (json2ubf err)
26 | ################################################################################
27 | service JUBFJUE_OK={
28 | "url":"/jubfjue_ok"
29 | ,"errors":"json2ubf"
30 | ,"timeout":5
31 | }
32 |
33 | service JUBFJUE_FAIL={
34 | "url":"/jubfjue_fail"
35 | ,"errors":"json2ubf"
36 | ,"timeout":5
37 | }
38 |
39 | service JUBFJUE_TOUT={
40 | "url":"/jubfjue_tout"
41 | ,"errors":"json2ubf"
42 | ,"timeout":1
43 | }
44 |
45 | # No such service - http 404
46 | service JUBFJUE_NENT={
47 | "url":"/jubfjue_nent"
48 | ,"errors":"json2ubf"
49 | ,"timeout":1
50 | }
51 | ################################################################################
52 | # JSON2UBF test case - http errors
53 | ################################################################################
54 | service JUBFHTE_OK={
55 | "url":"/jubfhte_ok"
56 | ,"errors":"http"
57 | ,"timeout":5
58 | }
59 |
60 | service JUBFHTE_FAIL={
61 | "url":"/jubfhte_fail"
62 | ,"errors":"http"
63 | ,"timeout":5
64 | }
65 |
66 | service JUBFHTE_TOUT={
67 | "url":"/jubfhte_tout"
68 | ,"errors":"http"
69 | ,"timeout":1
70 | }
71 | # 404
72 | service JUBFHTE_NENT={
73 | "url":"/jubfhte_nent"
74 | ,"errors":"http"
75 | ,"timeout":1
76 | }
77 | # 404 - remapped to tout
78 | service JUBFHTE_NENT_13={
79 | "url":"/jubfhte_nent"
80 | ,"errors":"http"
81 | ,"timeout":1
82 | ,"errors_fmt_http_map":"200:0,404:13,*:11"
83 | }
84 |
85 | ################################################################################
86 | # TEXT test case - text errors
87 | ################################################################################
88 |
89 | service TEXTTE_OK={
90 | "url":"/textte_ok"
91 | ,"errors":"text"
92 | ,"timeout":5
93 | }
94 |
95 | service TEXTTE_FAIL={
96 | "url":"/textte_fail"
97 | ,"errors":"text"
98 | ,"timeout":5
99 | }
100 |
101 | ################################################################################
102 | # JSON test case - json errors
103 | ################################################################################
104 |
105 | service JSONJE_OK={
106 | "url":"/jsonje_ok"
107 | ,"errors":"json"
108 | ,"timeout":5
109 | }
110 |
111 | service JSONJE_OKNS={
112 | "url":"/jsonje_okns"
113 | ,"errors":"json"
114 | ,"timeout":5
115 | ,"errfmt_json_onsucc":false
116 | }
117 |
118 | service JSONJE_OKASYNC={
119 | "url":"/jsonje_okasync"
120 | ,"errors":"json"
121 | ,"timeout":5
122 | }
123 |
124 | service JSONJE_FAIL={
125 | "url":"/jsonje_fail"
126 | ,"errors":"json"
127 | ,"timeout":5
128 | ,"errfmt_json_msg":"message"
129 | ,"errfmt_json_code":"code"
130 | }
131 |
132 | ################################################################################
133 | # RAW test case - text errors
134 | ################################################################################
135 |
136 | service RAWTE_OK={
137 | "url":"/rawte_ok"
138 | ,"errors":"text"
139 | ,"timeout":5
140 | }
141 |
142 | service RAWTE_FAIL={
143 | "url":"/rawte_fail"
144 | ,"errors":"text"
145 | ,"timeout":5
146 | }
147 |
148 | ################################################################################
149 | # ECHO tests, JSON2UBF
150 | ################################################################################
151 |
152 | # This echo host
153 | service ECHO_JSON2UBF={
154 | "url":"/echo_json2ubf"
155 | ,"errors":"json2ubf"
156 | ,"echo":true
157 | ,"echo_time":1
158 | ,"echo_max_fail":2
159 | ,"echo_min_ok":3
160 | ,"echo_conv":"json2ubf"
161 | ,"echo_data":"{\"T_STRING_FLD\":\"Some echo data...\"}"
162 | }
163 |
164 | # This depends on echo host ECHO_JSON2UBF
165 | # once it is up, the service DEP_JSON2UBF should be advertised
166 | service DEP_JSON2UBF={
167 | "url":"/jubfjue_ok"
168 | ,"errors":"json2ubf"
169 | ,"timeout":5
170 | ,"depends_on":"ECHO_JSON2UBF"
171 | }
172 |
173 | service DEP_JSON2UBF2={
174 | "url":"/jubfjue_ok"
175 | ,"errors":"json2ubf"
176 | ,"timeout":5
177 | ,"depends_on":"ECHO_JSON2UBF"
178 | }
179 |
180 | ################################################################################
181 | # ECHO tests, JSON
182 | ################################################################################
183 | # This echo host
184 | service ECHO_JSON={
185 | "url":"/echo_json"
186 | ,"errors":"json"
187 | ,"echo":true
188 | ,"echo_time":1
189 | ,"echo_max_fail":2
190 | ,"echo_min_ok":3
191 | ,"echo_conv":"json"
192 | ,"echo_data":"{\"StringField\":\"Hello Echo\"}"
193 | }
194 |
195 | service DEP_JSON={
196 | "url":"/dep_jsonhte"
197 | ,"errors":"http"
198 | ,"timeout":5
199 | ,"depends_on":"ECHO_JSON"
200 | }
201 | ################################################################################
202 | # ECHO tests, TEXT
203 | ################################################################################
204 | # This echo host
205 | service ECHO_STRING={
206 | "url":"/echo_string"
207 | ,"errors":"text"
208 | ,"echo":true
209 | ,"echo_time":1
210 | ,"echo_max_fail":2
211 | ,"echo_min_ok":3
212 | ,"echo_conv":"text"
213 | ,"echo_data":"This is echo string!"
214 | }
215 |
216 | service DEP_STRING={
217 | "url":"/dep_stringhte"
218 | ,"errors":"http"
219 | ,"timeout":5
220 | ,"depends_on":"ECHO_STRING"
221 | }
222 | ################################################################################
223 | # ECHO tests, RAW
224 | ################################################################################
225 | # This echo host
226 | service ECHO_RAW={
227 | "url":"/echo_raw"
228 | ,"errors":"text"
229 | ,"echo":true
230 | ,"echo_time":1
231 | ,"echo_max_fail":2
232 | ,"echo_min_ok":3
233 | ,"echo_conv":"raw"
234 | ,"echo_data":"AQIDBAUGBwgJEBESExQV"
235 | }
236 |
237 | service DEP_RAW={
238 | "url":"/dep_rawhte"
239 | ,"errors":"http"
240 | ,"timeout":5
241 | ,"depends_on":"ECHO_RAW"
242 | }
243 |
244 |
245 |
246 | ################################################################################
247 | # VIEW tests, json2view errors
248 | ################################################################################
249 |
250 | service VIEWERR_OK={
251 | "url":"/viewerr/ok"
252 | ,"errors":"json2view"
253 | ,"errfmt_view_msg":"rspmessage"
254 | ,"errfmt_view_code":"rspcode"
255 | ,"timeout":5
256 | }
257 |
258 | service VIEWERR_FAIL={
259 | "url":"/viewerr/fail"
260 | ,"errors":"json2view"
261 | ,"errfmt_view_msg":"rspmessage"
262 | ,"errfmt_view_code":"rspcode"
263 | ,"parseonerror":true
264 | ,"timeout":5
265 | }
266 |
267 | service VIEWERR_TOUT={
268 | "url":"/viewerr/tout"
269 | ,"errors":"json2view"
270 | ,"errfmt_view_msg":"rspmessage"
271 | ,"errfmt_view_code":"rspcode"
272 | ,"timeout":1
273 | }
274 |
275 | service VIEWHTTP_OK={
276 | "url":"/viewhttp/ok"
277 | ,"errors":"http"
278 | ,"timeout":5
279 | }
280 |
281 | service VIEWHTTP_FAIL={
282 | "url":"/viewhttp/fail"
283 | ,"errors":"http"
284 | ,"parseonerror":true
285 | ,"timeout":5
286 | }
287 |
288 |
289 | ################################################################################
290 | # ECHO tests, JSON2VIEW
291 | ################################################################################
292 | # This echo host
293 | service ECHO_JSON2VIEW={
294 | "url":"/echo_json2view"
295 | ,"errors":"json2view"
296 | ,"echo":true
297 | ,"echo_time":1
298 | ,"echo_max_fail":2
299 | ,"echo_min_ok":3
300 | ,"echo_conv":"json2view"
301 | ,"errfmt_view_msg":"rspmessage"
302 | ,"errfmt_view_code":"rspcode"
303 | #This is JSON2VIEW JSON format:
304 | ,"echo_data":"{\"REQUEST1\":{\"tshort1\": 5,\"tlong1\": 77777,\"tstring1\": [\"\",\"INCOMING TEST\"]}}"
305 | }
306 |
307 | # This depends on echo host ECHO_JSON2VIEW
308 | # once it is up, the service DEP_JSON2VIEW should be advertised
309 | service DEP_JSON2VIEW={
310 | "url":"/viewerr/ok"
311 | ,"errors":"json2view"
312 | , "errfmt_view_msg":"rspmessage"
313 | , "errfmt_view_code":"rspcode"
314 | ,"timeout":5
315 | ,"depends_on":"ECHO_JSON2UBF"
316 | }
317 |
318 | #
319 | # Moved down for second pass config read test
320 | #
321 | defaults={"urlbase":"https://localhost:8080"
322 | ,"errors":"http"
323 | ,"noreqfilersp": true
324 | ,"sslinsecure": true
325 | }
326 |
327 | [@restout/bigmsg]
328 | # Enduro/X debug string setup
329 | debug = tp=4 ndrx=4 iflags=detailed file= threaded=y
330 | gencore=1
331 | workers=5
332 | scan_time=7
333 |
334 | defaults={"urlbase":"http://localhost:8181"
335 | ,"errors":"http"
336 | ,"noreqfilersp": true
337 | }
338 |
339 | # Big messages (1M over the rest)
340 | service BIGMSG_REST={
341 | "url":"/bigmsg"
342 | ,"errors":"json2ubf"
343 | ,"timeout":5
344 | }
345 |
346 |
--------------------------------------------------------------------------------
/go/src/restincl/transactions.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Transaction API and context handling
3 | *
4 | * @file transactions.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "encoding/json"
37 | "fmt"
38 | "net/http"
39 | "ubftab"
40 |
41 | atmi "github.com/endurox-dev/endurox-go"
42 | )
43 |
44 | const (
45 | TX_REQ_HDR = "endurox-tptranid-req"
46 | TX_RSP_HDR = "endurox-tptranid-rsp"
47 |
48 | OP_TPBEGIN = "tpbegin"
49 | OP_TPCOMMIT = "tpcommit"
50 | OP_TPABORT = "tpabort"
51 | )
52 |
53 | /**
54 | * Transaction API request
55 | */
56 | type TxReqData struct {
57 | Operation string `json:"operation"`
58 | Timeout uint64 `json:"timeout"`
59 | Flags int64 `json:"flags"`
60 | Tptranid string `json:"tptranid"`
61 | }
62 |
63 | /**
64 | * Transaction API response
65 | */
66 | type TxRspData struct {
67 | Operation string `json:"operation,omitempty"`
68 | ErrorCode int `json:"error_code"`
69 | ErrorMessage string `json:"error_message"`
70 | Tptranid string `json:"tptranid,omitempty"`
71 | }
72 |
73 | /**
74 | * Transaction handler entry.
75 | * Assumes that buffers are encoded in "ext" mode
76 | * TODO: Needs to think about http status codes. Maybe in case of failure, we could
77 | * give basic indication to caller, that something failed.
78 | *
79 | * @param ac ATMI Context
80 | * @param buf ATMI buffer to call
81 | * @param svc service mapping to call
82 | * @param req request object
83 | * @param w response object
84 | * @param rctx request context
85 | * @param flags call flags
86 | */
87 | func txHandler(ac *atmi.ATMICtx, buf atmi.TypedBuffer, svc *ServiceMap, req *http.Request,
88 | w http.ResponseWriter, rctx *RequestContext, flags int64) (ret atmi.ATMIError) {
89 |
90 | var reqData TxReqData
91 | var rspData TxRspData
92 | var err atmi.ATMIError
93 | bufu, ok := buf.(*atmi.TypedUBF)
94 |
95 | if !ok {
96 | ac.TpLogError("ERROR: txHandler - got non UBF buffer")
97 | return atmi.NewCustomATMIError(atmi.TPESYSTEM, "Invalid buffer")
98 | }
99 |
100 | body, errU := bufu.BGetByteArr(ubftab.EX_IF_REQDATA, 0)
101 | if nil != errU {
102 |
103 | ac.TpLogError("ERROR: txHandler - failed to get EX_IF_REQDATA: %s",
104 | errU.Error())
105 |
106 | return atmi.NewCustomATMIError(atmi.TPESYSTEM,
107 | fmt.Sprintf("Failed to get ubftab.EX_IF_REQDATA: %s", errU.Error()))
108 | }
109 |
110 | //If we have valid buffer, we can start to generate
111 | //Normal json responses
112 | defer func() {
113 |
114 | http_status := http.StatusOK
115 |
116 | if nil != ret {
117 | rspData.ErrorCode = ret.Code()
118 | rspData.ErrorMessage = ret.Message()
119 | } else {
120 | rspData.ErrorCode = 0
121 | rspData.ErrorMessage = "Succeed"
122 | }
123 |
124 | //Return http response codes correspodingly & marshal the response
125 |
126 | if nil != ret && (ret.Code() == atmi.TPEINVAL || ret.Code() == atmi.TPEPROTO) {
127 |
128 | http_status = http.StatusBadRequest
129 |
130 | } else if nil != ret && ret.Code() > 0 {
131 |
132 | //in this case it is 500
133 | http_status = http.StatusInternalServerError
134 | }
135 |
136 | //Load the response body...
137 |
138 | rspBody, err := json.Marshal(&rspData)
139 |
140 | if nil != err {
141 | ac.TpLogError("Failed to prepare response: %s", err.Error())
142 | http_status = http.StatusInternalServerError
143 | } else {
144 |
145 | err := bufu.BChg(ubftab.EX_IF_RSPDATA, 0, rspBody)
146 |
147 | if err != nil {
148 | ac.TpLogError("Failed to set response body: %s", err.Error())
149 | http_status = http.StatusInternalServerError
150 | }
151 | }
152 |
153 | //Setup the response code finally
154 |
155 | if err := bufu.BChg(ubftab.EX_NETRCODE, 0, http_status); nil != err {
156 | ac.TpLogError("Failed to set EX_NETRCODE to %d: %s", http_status, err.Error())
157 | }
158 |
159 | }()
160 |
161 | //Parse the request...
162 | //Invalid request we
163 | errJ := json.Unmarshal(body, &reqData)
164 |
165 | if nil != errJ {
166 | return atmi.NewCustomATMIError(atmi.TPEINVAL,
167 | fmt.Sprintf("Failed to parse JSON request: %s", errJ.Error()))
168 | }
169 |
170 | rspData.Operation = reqData.Operation
171 | rspData.Tptranid = reqData.Tptranid
172 |
173 | //Check do we recognize the function
174 | ac.TpLogInfo("txHandler: operation: [%s], timeout: %d, flags: %d tptranid: [%s]",
175 | reqData.Operation, reqData.Timeout, reqData.Flags, reqData.Tptranid)
176 |
177 | if reqData.Operation == OP_TPCOMMIT || reqData.Operation == OP_TPABORT {
178 | //Resume transaction
179 | err = ac.TpResumeString(reqData.Tptranid, 0)
180 |
181 | if nil != err {
182 | ac.TpLogError("%s: failed to resume transaction: %s",
183 | reqData.Operation, err.Error())
184 |
185 | return err
186 | }
187 | }
188 |
189 | switch reqData.Operation {
190 |
191 | case OP_TPBEGIN:
192 |
193 | err = ac.TpBegin(reqData.Timeout, reqData.Flags)
194 |
195 | if nil != err {
196 | ac.TpLogError("Failed to begin transaction: %s", err.Error())
197 | return err
198 | }
199 |
200 | //Suspend transactions & get TID
201 | tid, err := ac.TpSuspendString(0)
202 |
203 | if nil != err {
204 | ac.TpLogError("tpbegin: Failed to suspend transaction: %s", err.Error())
205 | return err
206 | }
207 |
208 | rspData.Tptranid = tid
209 |
210 | ac.TpLogInfo("Started transaction: [%s]", rspData.Tptranid)
211 |
212 | case OP_TPCOMMIT:
213 | err = ac.TpCommit(0)
214 |
215 | if nil != err {
216 | ac.TpLogError("Failed to commit transaction: %s", err.Error())
217 | //In any case, context now becomes disasociated from tran
218 | return err
219 | }
220 |
221 | case OP_TPABORT:
222 |
223 | err = ac.TpAbort(0)
224 |
225 | if nil != err {
226 | ac.TpLogError("Failed to abort transaction: %s", err.Error())
227 | //In any case, context now becomes disasociated from tran
228 | return err
229 | }
230 |
231 | default:
232 | return atmi.NewCustomATMIError(atmi.TPEINVAL,
233 | fmt.Sprintf("Unsupported operation: [%s]", reqData.Operation))
234 |
235 | }
236 |
237 | return nil
238 |
239 | }
240 |
241 | /**
242 | * Transaction service call, in case if transaction headers are present
243 | * otherwise just normal call
244 | * @param ac ATMI Context
245 | * @param buf ATMI buffer to call
246 | * @param svc service mapping to call
247 | * @param req request object
248 | * @param w response object
249 | * @param rctx request context
250 | * @param flags call flags
251 | */
252 | func txCall(ac *atmi.ATMICtx, buf atmi.TypedBuffer, svc *ServiceMap, req *http.Request,
253 | w http.ResponseWriter, rctx *RequestContext, flags int64) atmi.ATMIError {
254 |
255 | var err atmi.ATMIError
256 |
257 | tidreq := req.Header.Get(TX_REQ_HDR)
258 |
259 | if tidreq != "" {
260 |
261 | var resum_flags int64
262 |
263 | if svc.TxNoOptim {
264 | resum_flags |= atmi.TPTXNOOPTIM
265 | }
266 |
267 | err = ac.TpResumeString(tidreq, resum_flags)
268 |
269 | if nil != err {
270 | ac.TpLogError("Failed to resume transaction [%s] for svc call [%s]",
271 | tidreq, svc.Svc)
272 | ac.UserLog("Failed to resume transaction [%s] for svc call [%s]",
273 | tidreq, svc.Svc)
274 | return err
275 | }
276 |
277 | ac.TpLogDebug("Resumed global transaction [%s]", tidreq)
278 | }
279 |
280 | if svc.NoAbort {
281 | flags |= atmi.TPNOABORT
282 | }
283 |
284 | _, err = ac.TpCall(svc.Svc, buf, flags|atmi.TPTRANSUSPEND)
285 |
286 | if ac.TpGetLev() > 0 {
287 |
288 | tidrsp, err_susp := ac.TpSuspendString(0)
289 |
290 | if nil != err_susp {
291 | ac.TpLogError("Failed to suspend transaction for %s call: %s", svc.Svc,
292 | err_susp.Message())
293 | ac.UserLog("Failed to suspend transaction for %s call: %s", svc.Svc,
294 | err_susp.Message())
295 | //Ignore and continue... (do not return tran header)
296 | } else {
297 | ac.TpLogDebug("Transaction suspended [%s]", tidrsp)
298 | w.Header().Set(TX_RSP_HDR, tidrsp)
299 | }
300 | }
301 |
302 | return err
303 | }
304 |
305 | /* vim: set ts=4 sw=4 et smartindent: */
306 |
--------------------------------------------------------------------------------
/go/src/tcpgatesv/netin.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Network -> Enduro/X
3 | *
4 | * @file netin.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | u "ubftab"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | //Allocate UBF buffer for holding the full
42 | //Hmm buf we have a problem here with error, as the interface appears to be the
43 | //same for UBF and ATMI, and also error codes to collide. But for now it is not
44 | //important.
45 | //@param con Connection object
46 | //@param corr Correlator
47 | //@param data Data received from network
48 | //@param isRsp true if request is response, else it is assumed as request
49 | //@return UBF buffer if no error, ATMI Error if problem occurred.
50 | func AllocReplyDataBuffer(ac *atmi.ATMICtx, con *ExCon, corr string, data []byte, isRsp bool) (*atmi.TypedUBF, atmi.ATMIError) {
51 |
52 | buf, err := ac.NewUBF(int64(len(data) + 1024))
53 | if nil != err {
54 | ac.TpLogError("Failed to allocate buffer: [%s] - dropping incoming message",
55 | err.Error())
56 | return nil, err
57 | }
58 |
59 | if err = buf.BChg(u.EX_NETGATEWAY, 0, MGateway); err != nil {
60 | ac.TpLogError("Failed to set EX_NETGATEWAY %d: %s", err.Code(), err.Message())
61 | return nil, err
62 | }
63 |
64 | if err = buf.BChg(u.EX_NETCONNID, 0, con.id_comp); err != nil {
65 | ac.TpLogError("Failed to set EX_NETCONNID %d: %s", err.Code(), err.Message())
66 | return nil, err
67 | }
68 |
69 | if err = buf.BChg(u.EX_NETDATA, 0, data); err != nil {
70 | ac.TpLogError("Failed to set EX_NETDATA %d: %s", err.Code(), err.Message())
71 | return nil, err
72 | }
73 |
74 | if "" != corr {
75 | if buf.BChg(u.EX_NETCORR, 0, corr); err != nil {
76 | ac.TpLogError("Failed to set EX_NETCORR %d: %s", err.Code(), err.Message())
77 | return nil, err
78 | }
79 | }
80 |
81 | //Setup IP/port our/their and role
82 | if err = buf.BChg(u.EX_NETOURIP, 0, con.ourip); err != nil {
83 | ac.TpLogError("Failed to set EX_NETOURIP %d: %s", err.Code(), err.Message())
84 | return nil, err
85 | }
86 |
87 | if err = buf.BChg(u.EX_NETOURPORT, 0, con.outport); err != nil {
88 | ac.TpLogError("Failed to set EX_NETOURPORT %d: %s", err.Code(), err.Message())
89 | return nil, err
90 | }
91 |
92 | //Setup IP/port our/their and role
93 | if err = buf.BChg(u.EX_NETTHEIRIP, 0, con.theirip); err != nil {
94 | ac.TpLogError("Failed to set EX_NETTHEIRIP %d: %s", err.Code(), err.Message())
95 | return nil, err
96 | }
97 |
98 | if err = buf.BChg(u.EX_NETTHEIRPORT, 0, con.theirport); err != nil {
99 | ac.TpLogError("Failed to set EX_NETTHEIRPORT %d: %s", err.Code(), err.Message())
100 | return nil, err
101 | }
102 |
103 | if err = buf.BChg(u.EX_NETCONMODE, 0, con.conmode); err != nil {
104 | ac.TpLogError("Failed to set EX_NETCONMODE %d: %s", err.Code(), err.Message())
105 | return nil, err
106 | }
107 |
108 | if isRsp {
109 | buf.BChg(u.EX_NERROR_CODE, 0, 0)
110 | buf.BChg(u.EX_NERROR_MSG, 0, "SUCCEED")
111 | }
112 |
113 | return buf, nil
114 | }
115 |
116 | //We have recieved new call from Network
117 | //So shall wait for new ATMI context & send the message in
118 | //This should be run on go routine.
119 | //@param data Data received from Network
120 | //@param bool set to false if do not need to continue (i.e. close conn)
121 | func NetDispatchCall(pool *XATMIPool, nr int, con *ExCon,
122 | preAllocUBF *atmi.TypedUBF, corr string, data []byte) {
123 |
124 | buf := preAllocUBF
125 | ac := pool.ctxs[nr]
126 |
127 | //Return to the caller
128 | defer func() {
129 | ac.TpLogInfo("About to put back XATMI-in object %d", nr)
130 | //put batch in channel
131 | pool.freechan <- nr
132 | }()
133 |
134 | var errA atmi.ATMIError
135 | //Setup UBF buffer, load the fields
136 | if nil == buf {
137 | buf, errA = AllocReplyDataBuffer(ac, con, corr, data, false)
138 |
139 | if errA != nil {
140 | ac.TpLogError("failed to create the net->ex UBF buffer: %s",
141 | errA.Message())
142 | return
143 | }
144 | } else {
145 | //Set the current context of the buffer
146 | buf.GetBuf().TpSetCtxt(ac)
147 | }
148 |
149 | //OK we are here, lets call the service
150 | //If we work on non req_reply mode, then just async call
151 |
152 | buf.TpLogPrintUBF(atmi.LOG_DEBUG, "Incoming message")
153 |
154 | //Full async mode
155 | // Feature #204 - allow in full async mode sync invopcation of incomings...
156 | if (RR_PERS_ASYNC_INCL_CORR == MReqReply ||
157 | RR_PERS_CONN_EX2NET == MReqReply) && !MIncomingSvcSync {
158 | ac.TpLogInfo("Calling in async mode (fully async or conn_ex2net mode)")
159 | _, errA := ac.TpACall(MIncomingSvc, buf, atmi.TPNOREPLY)
160 |
161 | if nil != errA {
162 | ac.TpLogError("Failed to acall [%s]: %s",
163 | MIncomingSvc, errA.Message())
164 | }
165 | } else {
166 | ac.TpLogInfo("Req-reply mode enabled and this is incoming call, " +
167 | "do call the service in sync mode")
168 |
169 | _, errA := ac.TpCall(MIncomingSvc, buf, atmi.TPNOTIME)
170 |
171 | if errA != nil {
172 | ac.TpLogError("Failed to call %s service: %d: %s",
173 | MIncomingSvc, errA.Code(), errA.Message())
174 | //Nothing to reply back
175 | } else {
176 | //Read the data block and reply back
177 | var b DataBlock
178 | b.data, errA = buf.BGetByteArr(u.EX_NETDATA, 0)
179 | if nil != errA {
180 | ac.TpLogError("Protocol error: failed to get "+
181 | "EX_NETDATA: %s", errA)
182 | //Shutdonw the sync incoming connection only
183 | //If needed (i.e. if it one connection per request)
184 | con.shutdown <- true
185 |
186 | } else {
187 | ac.TpLogInfo("Got message from EX, sending to net len: %d",
188 | len(b.data))
189 | //Maybe send to channel for reply
190 | //And then shutdown (if needed, will by done by con it self)
191 | //How about locking, connection is already locked!!!!
192 |
193 | //Really, the incoming thread already holds the lock!
194 | //ac.TpLogDebug("No lock mode")
195 | //b.nolock = true
196 | con.outgoing <- &b
197 | }
198 | }
199 | }
200 | }
201 |
202 | //Dispatch connection answer
203 |
204 | //@param call Call data block (what caller thread actually made)
205 | //@param data Data block received from network
206 | //@param bool ptr for finish off parameter
207 | func NetDispatchConAnswer(ac *atmi.ATMICtx, con *ExCon, block *DataBlock, data []byte, doContinue *bool) {
208 |
209 | //Setup UBF buffer, load the fields
210 | buf, err := AllocReplyDataBuffer(ac, con, "", data, true)
211 |
212 | if err != nil {
213 | ac.TpLogError("failed to create the net->ex UBF buffer: %s",
214 | err.Message())
215 | return
216 | }
217 |
218 | //Network answer on connection
219 | block.atmi_chan <- buf
220 |
221 | //We should shutdown the connection if this is request/reply mode
222 | //with out persistent connections
223 | if MReqReply == RR_NONPERS_EX2NET {
224 |
225 | ac.TpLogWarn("Non peristent connection mode, got answer from network" +
226 | " - requesting connection shutdown")
227 | *doContinue = false
228 | }
229 | }
230 |
231 | //Dispatch connection answer
232 | //@param call Call data block (what caller thread actually made)
233 | //@param data Data block received from network
234 | //@param bool ptr for finish off parameter
235 | func NetDispatchCorAnswer(ac *atmi.ATMICtx, con *ExCon, block *DataBlock,
236 | buf *atmi.TypedUBF, doContinue *bool) {
237 | ac.TpLogInfo("Doing reply to correlated ex->net call")
238 | block.atmi_chan <- buf //Send the data to caller
239 | }
240 |
241 | //Get correlator id from incoming message. The correlator is set in UBF buffer
242 | //@param ac ATMI Context
243 | //@param buf ATMI buffer
244 | //@return ATMI error if fail, or nil if all ok
245 | func NetGetCorID(ac *atmi.ATMICtx, buf *atmi.TypedUBF) (string, atmi.ATMIError) {
246 |
247 | _, err := ac.TpCall(MCorrSvc, buf, 0)
248 |
249 | if nil != err {
250 | ac.TpLogError("Failed to call [%s] service: %s",
251 | MCorrSvc, err.Message())
252 | return "", err
253 | }
254 |
255 | ret, _ := buf.BGetString(u.EX_NETCORR, 0)
256 | ac.TpLogInfo("Got correlation from service: [%s]", ret)
257 |
258 | return ret, nil
259 | }
260 |
261 | /* vim: set ts=4 sw=4 et smartindent: */
262 |
--------------------------------------------------------------------------------
/pkg/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ##
2 | ## @brief Connectivity packaging scripts
3 | ##
4 | ## @file CMakeLists.txt
5 | ##
6 | ## -----------------------------------------------------------------------------
7 | ## Enduro/X Middleware Platform for Distributed Transaction Processing
8 | ## Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | ## Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | ## This software is released under one of the following licenses:
11 | ## AGPL or Mavimax's license for commercial use.
12 | ## -----------------------------------------------------------------------------
13 | ## AGPL license:
14 | ##
15 | ## This program is free software; you can redistribute it and/or modify it under
16 | ## the terms of the GNU Affero General Public License, version 3 as published
17 | ## by the Free Software Foundation;
18 | ##
19 | ## This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | ## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | ## PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | ## for more details.
23 | ##
24 | ## You should have received a copy of the GNU Affero General Public License along
25 | ## with this program; if not, write to the Free Software Foundation, Inc.,
26 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | ##
28 | ## -----------------------------------------------------------------------------
29 | ## A commercial use license is available from Mavimax, Ltd
30 | ## contact@mavimax.com
31 | ## -----------------------------------------------------------------------------
32 | ##
33 |
34 | cmake_minimum_required (VERSION 3.1)
35 | project (ENDUROX-CONNECT)
36 | set(VERSION "8.0.8")
37 | set(PROJ_NAME "Enduro/X Connectivity Module")
38 | set(RELEASE "1")
39 |
40 | set(CMAKE_MODULE_PATH $ENV{CMAKE_MODULE_PATH} ${CMAKE_MODULE_PATH} "/usr/share/endurox/cmake")
41 | include(ex_osver)
42 |
43 | ################################################################################
44 | # Process any required includes
45 | ################################################################################
46 | ex_osver_include()
47 | ################################################################################
48 |
49 |
50 | ################################################################################
51 | # Check versions if defined, export build env
52 | ################################################################################
53 |
54 | if(DEFINED ENV{NDRX_BLD_VERSION})
55 | IF(NOT $ENV{NDRX_BLD_VERSION} MATCHES ${VERSION})
56 | message( FATAL_ERROR "Invalid versions: ENV: [$ENV{NDRX_BLD_VERSION}] Code: [${VERSION}]" )
57 | endif()
58 | endif()
59 |
60 | if(DEFINED ENV{NDRX_BLD_RELEASE})
61 | set(RELEASE $ENV{NDRX_BLD_RELEASE})
62 | endif()
63 |
64 | message("CMake RELEASE = ${RELEASE}")
65 |
66 | SET (NDRX_BLD_PRODUCT $ENV{NDRX_BLD_PRODUCT})
67 | SET (NDRX_BLD_SYSTEM $ENV{NDRX_BLD_SYSTEM})
68 | SET (NDRX_BLD_CONFIG $ENV{NDRX_BLD_CONFIG})
69 | SET (NDRX_BLD_VERSION $ENV{NDRX_BLD_VERSION})
70 | SET (NDRX_BLD_RELEASE $ENV{NDRX_BLD_RELEASE})
71 | SET (NDRX_BLD_TAG $ENV{NDRX_BLD_TAG})
72 | SET (NDRX_BLD_BRANCH $ENV{NDRX_BLD_BRANCH})
73 | SET (NDRX_BLD_COMMIT $ENV{NDRX_BLD_COMMIT})
74 | SET (NDRX_BLD_FLAGS $ENV{NDRX_BLD_FLAGS})
75 |
76 |
77 | ################################################################################
78 | # OS Configuration
79 | ################################################################################
80 |
81 | find_program(A2X_EXECUTABLE NAMES a2x)
82 |
83 |
84 | EXEC_PROGRAM(uname ARGS -a OUTPUT_VARIABLE _TMP_CMAKE_OS_NAME)
85 | string(REGEX MATCH "^[a-zA-Z0-9-]*" _TMP_CMAKE_OS_NAME_EXTR ${_TMP_CMAKE_OS_NAME})
86 | string(TOUPPER ${_TMP_CMAKE_OS_NAME_EXTR} CMAKE_OS_NAME)
87 |
88 | message("CMake CMAKE_OS_NAME = ${CMAKE_OS_NAME}")
89 | message("CMake CMAKE_C_COMPILER_ID = ${CMAKE_C_COMPILER_ID}")
90 | message("CMake CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
91 |
92 | if( "${CMAKE_OS_NAME}" STREQUAL "LINUX" )
93 | set(EX_OS_LINUX "1")
94 | elseif("${CMAKE_OS_NAME}" STREQUAL "AIX")
95 | set(EX_OS_AIX "1")
96 | set ( CMAKE_C_FLAGS "-D_SEM_SEMUN_UNDEFINED -D_MSGQSUPPORT -D_THREAD_SAFE -pthread -maix64 -Wl,-brtl -Wl,-G ${CMAKE_C_FLAGS}")
97 | set ( CMAKE_CXX_FLAGS "-D_SEM_SEMUN_UNDEFINED -D_MSGQSUPPORT -D_THREAD_SAFE -pthread -maix64 -Wl,-brtl -Wl,-G ${CMAKE_CXX_FLAGS}")
98 | elseif("${CMAKE_OS_NAME}" STREQUAL "HP-UX")
99 | set(EX_OS_HPUX "1")
100 | elseif("${CMAKE_OS_NAME}" STREQUAL "SUNOS")
101 | set(EX_OS_SUNOS "1")
102 | elseif("${CMAKE_OS_NAME}" STREQUAL "FREEBSD")
103 | set(EX_OS_FREEBSD "1")
104 | elseif("${CMAKE_OS_NAME}" STREQUAL "CYGWIN")
105 | set(EX_OS_CYGWIN "1")
106 | elseif("${CMAKE_OS_NAME}" STREQUAL "DARWIN")
107 | set(EX_OS_DARWIN "1")
108 | # Unkonwn OS:
109 | else()
110 | message( FATAL_ERROR "Unsupported OS" )
111 | endif()
112 |
113 |
114 | if(${CMAKE_OS_NAME} STREQUAL "DARWIN")
115 | set(LIB_SUFFIX "")
116 | elseif ("${LIB64}" STREQUAL "TRUE")
117 | set(LIB_SUFFX 64)
118 | else()
119 | set(LIB_SUFFIX "")
120 | endif()
121 |
122 | set(INSTALL_LIB_DIR lib${LIB_SUFFIX} CACHE PATH "Installation directory for libraries")
123 | mark_as_advanced(INSTALL_LIB_DIR)
124 | MESSAGE( STATUS "INSTALL_LIB_DIR: " ${INSTALL_LIB_DIR} )
125 | ################################################################################
126 | # Files to install
127 | ################################################################################
128 |
129 | install (FILES
130 | ../go/src/tcpgatesv/tcpgatesv
131 | ../go/src/restincl/restincl
132 | ../go/src/restoutsv/restoutsv
133 | PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
134 | DESTINATION bin)
135 |
136 | # check that a2x actually works, on aix there is a2x but it is not asciidoc
137 |
138 | execute_process(COMMAND a2x "--version" RESULT_VARIABLE RET)
139 | if(A2X_EXECUTABLE)
140 |
141 | if( NOT ${RET} MATCHES "0")
142 | message("a2x does not work - disabling doc...")
143 | unset(A2X_EXECUTABLE)
144 | elseif()
145 | # Install manpages (if any
146 | install (FILES
147 | ../doc/manpage/restincl.8
148 | ../doc/manpage/restousv.8
149 | ../doc/manpage/tcpgatesv.8
150 | DESTINATION share/man/man8)
151 |
152 | install (FILES
153 | ../doc/manpage/tcpgatesv.html
154 | ../doc/manpage/restincl.html
155 | ../doc/manpage/restoutsv.html
156 | DESTINATION share/endurox-connect/doc/html/manpage)
157 |
158 | install (FILES
159 | ../doc/manpage/docbook-xsl.css
160 | DESTINATION share/endurox-connect/doc/html/manpage
161 | OPTIONAL)
162 |
163 | install (FILES
164 | ../doc/restinout_user_guide.html
165 | ../doc/tcpgatesv_user_guide.html
166 | ../doc/nonpers_sync_ex_to_net.png
167 | ../doc/nonpers_sync_net_to_ex.png
168 | ../doc/pers_async_ex_to_net_wo_corr.png
169 | ../doc/pers_async_net_to_ex_w_corr.png
170 | ../doc/pers_async_net_to_ex_wo_corr.png
171 | ../doc/pers_sync_ex_to_net_connid.png
172 | ../doc/pers_sync_net_to_ex.png
173 | ../doc/restinout_tutor_1.png
174 | DESTINATION share/endurox-connect/doc/html/guides)
175 |
176 | install (FILES
177 | ../doc/docbook-xsl.css
178 | DESTINATION share/endurox-connect/doc/html/guides
179 | OPTIONAL)
180 | endif()
181 | endif()
182 |
183 | ################################################################################
184 | # Packages
185 | ################################################################################
186 | ex_osver()
187 | ex_cpuarch()
188 |
189 | MESSAGE( "CPack:Debug: CMAKE_SYSTEM_NAME = " ${CMAKE_SYSTEM_NAME} )
190 | MESSAGE( "CPack:Debug: CMAKE_SYSTEM_PROCESSOR = " ${CMAKE_SYSTEM_PROCESSOR} )
191 | set(CPACK_MONOLITHIC_INSTALL 1)
192 |
193 | find_program(RPMPROG "rpmbuild")
194 | find_program(APTPROG "dpkg")
195 |
196 | # avoid file /usr/share/man from install of endurox-3.5.1-1.x86_64 conflicts with file from package filesystem-3.2-21.el7.x86_64
197 | # problems...
198 | set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/share/man
199 | /usr/share/man/man3
200 | /usr/share/man/man5
201 | /usr/share/man/man8
202 | /usr/share/java
203 | /usr/lib64/pkgconfig
204 | /usr/lib/pkgconfig)
205 | message("Excl: ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}")
206 |
207 | set(CPACK_GENERATOR "TGZ")
208 | if(RPMPROG)
209 | message("Outputting RPM")
210 | set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM")
211 | endif()
212 |
213 | if(APTPROG)
214 | message("Outputting DEB")
215 | set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB")
216 | endif()
217 |
218 | INCLUDE (${CMAKE_ROOT}/Modules/CheckTypeSize.cmake)
219 | CHECK_TYPE_SIZE("void*" EX_SIZEOF_VOIDPTR)
220 | MATH (EXPR EX_PLATFORM_BITS "${EX_SIZEOF_VOIDPTR} * 8")
221 |
222 | message("Generator: ${CPACK_GENERATOR}")
223 |
224 | set(CPACK_PACKAGE_CONTACT "contact@mavimax.com")
225 | set(CPACK_PACKAGE_VERSION ${VERSION})
226 | set(CPACK_PACKAGE_VENDOR "Mavimax Ltd")
227 | #set(CPACK_DEBIAN_PACKAGE_DEPENDS "endurox")
228 | #set(CPACK_RPM_PACKAGE_REQUIRES "endurox")
229 | string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LO)
230 | message("CPack:Debug: PROJECT NAME = ${PROJECT_NAME_LO}")
231 | set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME_LO}-${VERSION}-${RELEASE}.${LSB_RELEASE_OUTPUT_OS}${LSB_RELEASE_OUTPUT_VER}.${EX_CPU_ARCH})
232 | string(TOLOWER ${CPACK_PACKAGE_FILE_NAME} CPACK_PACKAGE_FILE_NAME)
233 | message("CPack:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
234 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Enduro/X Connectivity Module")
235 | set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION})
236 | set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION})
237 | set(CPACK_RPM_PACKAGE_AUTOREQ "0")
238 | #set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/Debian/postinst")
239 |
240 | include(CPack)
241 | ################################################################################
242 |
243 |
244 | # vim: set ts=4 sw=4 et smartindent:
245 |
--------------------------------------------------------------------------------
/go/src/tcpgatesv/periodic.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief This module contains periodic callback processing
3 | *
4 | * @file periodic.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "exutil"
37 |
38 | atmi "github.com/endurox-dev/endurox-go"
39 | )
40 |
41 | //Zero sending periodic stopwatch
42 | var MStatusRefreshStopWatch exutil.StopWatch
43 | var MInIdleCheckStopWatch exutil.StopWatch
44 |
45 | //Send zero
46 | func RunZero(ac *atmi.ATMICtx, con *ExCon) {
47 |
48 | var block DataBlock
49 |
50 | if MFramingOffset > 0 {
51 | //Go by default set to 0
52 | block.data = make([]byte, MFramingLen)
53 | }
54 |
55 | p_block := &block
56 | ac.TpLogInfo("Sending zero length message to id:%d conn_id: %d ",
57 | con.id, con.id_comp)
58 |
59 | select {
60 | case con.outgoing <- p_block:
61 | default:
62 | ac.TpLogDebug("No zero msg -> channel full")
63 | }
64 |
65 | }
66 |
67 | //Check activity over open conns
68 | //So that if we have not received anyting
69 | func RunCheckInIdleChk(ac *atmi.ATMICtx) {
70 |
71 | //Lock all connections
72 | MConnMutex.Lock()
73 | for _, v := range MConnectionsComp {
74 |
75 | if v.is_open {
76 |
77 | spent := v.inIdle.GetDetlaSec()
78 | if spent > MInIdleMax {
79 | ac.TpLogWarn("RESET: Connect %d/%d not received any data in %d sec "+
80 | "(already spent: %d sec) - resetting conn",
81 | v.id, v.id_comp, MInIdleMax, spent)
82 | //Close connection
83 | v.shutdown <- true
84 | }
85 |
86 | } else {
87 | ac.TpLogInfo("conn %d/%d is not yet open - not sending zero msg",
88 | v.id, v.id_comp)
89 | }
90 | }
91 |
92 | MConnMutex.Unlock()
93 | }
94 |
95 | //Send zero length messages over the channels
96 | func RunStatusRefresh(ac *atmi.ATMICtx) {
97 |
98 | //Lock all connections
99 | MConnMutex.Lock()
100 | var i int64
101 |
102 | for i = 1; i <= MMaxConnections; i++ {
103 |
104 | if nil != MConnectionsSimple[i] && MConnectionsSimple[i].is_open {
105 | ac.TpLogInfo("REFRESH: Notify connection %d UP", i)
106 |
107 | NotifyStatus(ac, i, MConnectionsSimple[i].id_comp, FLAG_CON_ESTABLISHED,
108 | MConnectionsSimple[i])
109 | } else {
110 | ac.TpLogInfo("REFRESH: Notify connection %d DOWN", i)
111 | NotifyStatus(ac, i, atmi.FAIL, FLAG_CON_DISCON, nil)
112 | }
113 | }
114 |
115 | MConnMutex.Unlock()
116 |
117 | }
118 |
119 | //Check the outgoint connections
120 | func CheckDial(ac *atmi.ATMICtx) {
121 |
122 | //var openConns int64 = MMaxConnections - int64(len(MConnections))
123 | var i int64
124 |
125 | ac.TpLogInfo("CheckDial: Active connection, checking outgoing connections...")
126 |
127 | for i = GetOpenConnectionCount(); i < MMaxConnections; i++ {
128 |
129 | //Spawn new connection threads
130 | var con ExCon
131 |
132 | SetupConnection(&con)
133 |
134 | //1. Prepare connection block
135 | MConnMutex.Lock()
136 | con.id, con.id_stamp, con.id_comp = GetNewConnectionId(ac)
137 |
138 | if con.id == FAIL {
139 | ac.TpLogError("Failed to get connection id - max reached?")
140 | MConnMutex.Unlock()
141 | break
142 | }
143 |
144 | //2. Add to hash, -- why not 2017/09/29 - we get the same connection ids...
145 | //when they are not connect but new ids are generated?
146 | /*
147 | mvitolin 2017/01/25 do it when connection is established in GoDial*/
148 |
149 | MConnectionsSimple[con.id] = &con
150 | MConnectionsComp[con.id_comp] = &con
151 |
152 | MConnMutex.Unlock()
153 |
154 | //3. and spawn the routine...
155 | go GoDial(&con, nil)
156 | }
157 |
158 | }
159 |
160 | //Test is call block timed out
161 | //@param v Call block
162 | //@return true - timed out, false - call not timed out
163 | func IsBlockTimeout(ac *atmi.ATMICtx, v *DataBlock) bool {
164 |
165 | cur := exutil.GetEpochMillis()
166 | sum := v.tstamp_sent + MReqReplyTimeout
167 | ac.TpLogDebug("Testing tout: tstamp_sent=%d, "+
168 | "MReqReplyTimeout=%d, sum=%d, current=%d, delta=%d",
169 | v.tstamp_sent, MReqReplyTimeout,
170 | sum, cur,
171 | (cur - v.tstamp_sent))
172 |
173 | if sum < cur {
174 | ac.TpLogWarn("Call timed out!")
175 | return true
176 | }
177 |
178 | return false
179 | }
180 |
181 | //Check the connection timeouts
182 | //if needed generate timeout-response
183 | //and repond to service. Remove from waiter list
184 | //if timed out
185 | //@param ac ATMI Context
186 | func CheckTimeouts(ac *atmi.ATMICtx) atmi.ATMIError {
187 |
188 | //Lock the channels
189 | //The message shall not appear in both list correlated & by connection
190 | MConWaiterMutex.Lock()
191 | ac.TpLogDebug("Checking sync connection lists for timeouts")
192 | for k, v := range MConWaiter {
193 |
194 | if MReqReply == RR_PERS_CONN_EX2NET || MReqReply == RR_PERS_CONN_NET2EX ||
195 | MReqReply == RR_NONPERS_EX2NET || MReqReply == RR_NONPERS_NET2EX {
196 |
197 | if IsBlockTimeout(ac, v) {
198 | ac.TpLogWarn("Call expired!")
199 | buf, err := GenErrorUBF(ac, 0, atmi.NETOUT,
200 | "Timed out waiting for answer...")
201 |
202 | if nil == err {
203 | //Remove from list
204 | delete(MConWaiter, k)
205 | ac.TpLogInfo("Sending reply back to ATMI")
206 | v.atmi_chan <- buf
207 | ac.TpLogInfo("Sending reply back to ATMI, done")
208 |
209 | //Will kill a connection
210 | //Because the other end will might sent reply
211 | //later and that will confuse next caller.
212 | ac.TpLogInfo("Killing connection")
213 | ac.TpLogDebug("v=%p", v)
214 | ac.TpLogDebug("v.con=%p", v.con)
215 |
216 | v.con.shutdown <- true
217 | ac.TpLogInfo("Killing connection, done")
218 |
219 | } else {
220 | MConWaiterMutex.Unlock()
221 | return err
222 | }
223 | }
224 | }
225 | }
226 | MConWaiterMutex.Unlock()
227 |
228 | MCorrWaiterMutex.Lock()
229 | ac.TpLogDebug("Checking async correlation connection lists for timeout")
230 | for k, v := range MCorrWaiter {
231 |
232 | if v.corr != "" || MReqReply == RR_NONPERS_EX2NET ||
233 | MReqReply == RR_PERS_CONN_EX2NET {
234 |
235 | if IsBlockTimeout(ac, v) {
236 | buf, err := GenErrorUBF(ac, 0, atmi.NETOUT,
237 | "Timed out waiting for answer...")
238 |
239 | if nil == err {
240 | //Remove from list
241 | delete(MCorrWaiter, k)
242 | ac.TpLogInfo("Sending reply back to ATMI")
243 | v.atmi_chan <- buf
244 | ac.TpLogInfo("Sending reply back to ATMI, done")
245 |
246 | //Kill the connection, if non persistent
247 | if MReqReply == RR_NONPERS_EX2NET ||
248 | MReqReply == RR_PERS_CONN_EX2NET {
249 | ac.TpLogInfo("Killing connection")
250 | ac.TpLogDebug("v=%p", v)
251 | ac.TpLogDebug("v.con=%p", v.con)
252 | v.con.shutdown <- true
253 | ac.TpLogInfo("Killing connection, done")
254 | }
255 |
256 | } else {
257 | MCorrWaiterMutex.Unlock()
258 | return err
259 | }
260 | }
261 | }
262 | }
263 | MCorrWaiterMutex.Unlock()
264 |
265 | return nil
266 |
267 | }
268 |
269 | //Periodic callback function
270 | //Hmm do we have some context here?
271 | //We will spawn connections here..
272 | func Periodic(ac *atmi.ATMICtx) int {
273 |
274 | ret := atmi.SUCCEED
275 | //if we are active, check that we have enought connections
276 | if MType == CON_TYPE_ACTIVE && (MReqReply == RR_PERS_ASYNC_INCL_CORR ||
277 | MReqReply == RR_PERS_CONN_EX2NET) {
278 | CheckDial(ac)
279 | }
280 |
281 | if err := CheckTimeouts(ac); nil != err {
282 |
283 | ac.TpLogError("Failed check timeouts: %s - Aborting...",
284 | err.Message())
285 | return atmi.FAIL
286 |
287 | }
288 |
289 | if MStatusRefresh > 0 && MStatusRefreshStopWatch.GetDetlaSec() > int64(MStatusRefresh) {
290 | ac.TpLogInfo("Time for status refresh messages to be sent...")
291 |
292 | RunStatusRefresh(ac)
293 | MStatusRefreshStopWatch.Reset()
294 |
295 | }
296 |
297 | //Check the idle time incoming activitiy, if no messages received in given
298 | //time frame then connection is reset
299 | if MInIdleCheck > 0 && MInIdleCheckStopWatch.GetDetlaSec() > MInIdleCheck {
300 | ac.TpLogInfo("Time for idle connection checks with no incomming traffic")
301 |
302 | RunCheckInIdleChk(ac)
303 | MInIdleCheckStopWatch.Reset()
304 |
305 | }
306 |
307 | //TODO: Check for any outstanding network calls...
308 | //Send the timeout message of tout got.
309 | //Close the connection if req/reply..
310 |
311 | if MShutdown == RUN_SHUTDOWN_FAIL {
312 | //Hmm does not cause shutdown!!!
313 | ac.TpLogWarn("Fail state shutdown requested! - Aborting...")
314 | ret = atmi.FAIL
315 | }
316 |
317 | return ret
318 | }
319 |
320 | /* vim: set ts=4 sw=4 et smartindent: */
321 |
--------------------------------------------------------------------------------
/tests/02_tcpgatesv/runtime/conf/ndrxconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
12 | 5
13 |
14 |
17 | 6
18 |
19 |
22 | 1
23 |
24 |
27 | 1
28 |
29 |
32 | 5
33 |
34 |
37 |
38 |
42 | 20
43 |
44 |
45 |
50 | Y
51 |
52 |
53 |
54 |
55 | 1
56 | 2
57 |
58 |
61 | 1
62 |
63 |
67 | 2
68 |
69 |
72 | 1
73 |
74 |
79 | 40
80 |
81 |
85 | 1
86 |
87 |
91 | 1
92 |
93 |
96 | Y
97 |
98 | 3,2,9
99 |
100 |
101 |
102 | 1
103 | 1
104 | 1
105 | -e ${NDRX_APPHOME}/log/cconfsrv.log -r
106 |
107 |
108 | 2
109 | 2
110 | 20
111 | -e ${NDRX_APPHOME}/log/tpevsrv.log -r
112 |
113 |
114 | 3
115 | 3
116 | 40
117 | RM1TMQ
118 | -e ${NDRX_APPHOME}/log/tmsrv-rm1.log -r -- -t1 -l${NDRX_APPHOME}/tmlogs/rm1
119 |
120 |
121 | 1
122 | 1
123 | 60
124 | RM1TMQ
125 | -e ${NDRX_APPHOME}/log/tmqueue-rm1.log -r -- -s1
126 |
127 |
128 | 1
129 | 1
130 | 150
131 | -e ${NDRX_APPHOME}/log/tpbridge_2.log -r
132 | -f -n2 -r -i 172.0.0.1 -p 21003 -tA -z30
133 |
134 |
135 | 1
136 | 1
137 | 500
138 | -e ${NDRX_APPHOME}/log/testsv.log -r
139 |
140 |
141 | pers/async/active
142 | 1
143 | 1
144 | 200
145 | -e ${NDRX_APPHOME}/log/tcpgatesv-async-active.log -r
146 |
147 |
148 | pers/async/passive
149 | 1
150 | 1
151 | 210
152 | -e ${NDRX_APPHOME}/log/tcpgatesv-async-passive.log -r
153 |
154 |
155 | pers/asyncsync/active
156 | 1
157 | 1
158 | 215
159 | -e ${NDRX_APPHOME}/log/tcpgatesv-asyncsync-active.log -r
160 |
161 |
162 | pers/asyncsync/passive
163 | 1
164 | 1
165 | 216
166 | -e ${NDRX_APPHOME}/log/tcpgatesv-asyncsync-passive.log -r
167 |
168 |
169 | pers/sync/active
170 | 1
171 | 1
172 | 220
173 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-active.log -r
174 |
175 |
176 | pers/sync/passive
177 | 1
178 | 1
179 | 230
180 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-passive.log -r
181 |
182 |
183 | nonpers/active
184 | 1
185 | 1
186 | 240
187 | -e ${NDRX_APPHOME}/log/tcpgatesv-nonpers-active.log -r
188 |
189 |
190 | nonpers/pasive
191 | 1
192 | 1
193 | 250
194 | -e ${NDRX_APPHOME}/log/tcpgatesv-nonpers-passive.log -r
195 |
196 |
197 | pers/async/active/idlerst
198 | 1
199 | 1
200 | 260
201 | -e ${NDRX_APPHOME}/log/tcpgatesv-async-active-idlerst.log -r
202 |
203 |
204 | pers/async/passive/idlerst
205 | 1
206 | 1
207 | 270
208 | -e ${NDRX_APPHOME}/log/tcpgatesv-async-passive-idlerst.log -r
209 |
210 |
211 | pers/async/active/idlerstact
212 | 1
213 | 1
214 | 280
215 | -e ${NDRX_APPHOME}/log/tcpgatesv-async-active-idlerstact.log -r
216 |
217 |
218 | pers/async/passive/idlerstact
219 | 1
220 | 1
221 | 290
222 | -e ${NDRX_APPHOME}/log/tcpgatesv-async-passive-idlerstact.log -r
223 |
224 |
225 |
226 | pers/sync_offset_incl/active
227 | 1
228 | 1
229 | 300
230 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset_incl-active.log -r
231 |
232 |
233 | pers/sync_offset_incl/passive
234 | 1
235 | 1
236 | 310
237 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset_incl-passive.log -r
238 |
239 |
240 | pers/sync_offset/active
241 | 1
242 | 1
243 | 320
244 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset-active.log -r
245 |
246 |
247 | pers/sync_offset/passive
248 | 1
249 | 1
250 | 330
251 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset-passive.log -r
252 |
253 |
254 |
255 |
256 | pers/sync_offset_incl_P/active
257 | 1
258 | 1
259 | 331
260 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset_incl_P-active.log -r
261 |
262 |
263 | pers/sync_offset_incl_P/passive
264 | 1
265 | 1
266 | 332
267 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset_incl_P-passive.log -r
268 |
269 |
270 | pers/sync_offset_p/active
271 | 1
272 | 1
273 | 333
274 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset_p-active.log -r
275 |
276 |
277 | pers/sync_offset_p/passive
278 | 1
279 | 1
280 | 334
281 | -e ${NDRX_APPHOME}/log/tcpgatesv-pers-sync-offset_p-passive.log -r
282 |
283 |
284 |
285 |
286 | pers/sequence/active
287 | 1
288 | 1
289 | 340
290 | -e ${NDRX_APPHOME}/log/tcpgatesv-sequence-active.log -r
291 |
292 |
293 | pers/sequence/passive
294 | 1
295 | 1
296 | 350
297 | -e ${NDRX_APPHOME}/log/tcpgatesv-sequence-passive.log -r
298 |
299 |
300 |
301 | pers/tls/active
302 | 1
303 | 1
304 | 400
305 | -e ${NDRX_APPHOME}/log/tcpgatesv-tls-active.log -r
306 |
307 |
308 | pers/tls/passive
309 | 1
310 | 1
311 | 410
312 | -e ${NDRX_APPHOME}/log/tcpgatesv-tls-passive.log -r
313 |
314 |
315 |
316 | 1
317 | 1
318 | 9999
319 | -e ${NDRX_APPHOME}/log/cpmsrv.log -r -- -k3 -i1
320 |
321 |
322 |
323 |
326 |
327 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
--------------------------------------------------------------------------------
/tests/03_restout/src/testcl/testcl.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "fmt"
7 | "os"
8 | "strconv"
9 | u "ubftab"
10 |
11 | atmi "github.com/endurox-dev/endurox-go"
12 | )
13 |
14 | /*
15 | #include
16 | */
17 | import "C"
18 |
19 | const (
20 | ProgSection = "testcl"
21 | )
22 |
23 | var MSomeConfigFlag string = ""
24 | var MSomeOtherConfigFlag int = 0
25 | var MErrorCode int = atmi.TPMINVAL
26 |
27 | type TestJSONMsg struct {
28 | StringField string `json:"StringField"`
29 | StringField2 string `json:"StringField2"`
30 | NumField int `json:"NumField"`
31 | NumField2 int `json:"NumField2"`
32 | BoolField bool `json:"BoolField"`
33 | BoolField2 bool `json:"BoolField2"`
34 | }
35 |
36 | //Test big message over the rest interface
37 | func BigMsg(ac *atmi.ATMICtx, cmd string, svc string, times string) error {
38 |
39 | nrTimes, _ := strconv.Atoi(times)
40 |
41 | for i := 0; i < nrTimes; i++ {
42 | buf, err := ac.NewUBF(1024*1024 + 1024)
43 |
44 | if err != nil {
45 | return errors.New(err.Error())
46 | }
47 |
48 | testdata := make([]byte, 1024*1024)
49 |
50 | for i := 0; i < len(testdata); i++ {
51 | testdata[i] = byte((i + 1) % 255)
52 | }
53 |
54 | if err := buf.BChg(u.T_CARRAY_FLD, 0, testdata); nil != err {
55 | fmt.Printf("! ATMI Error %d:[%s]\n", err.Code(), err.Message())
56 | return errors.New(fmt.Sprintf("! ATMI Error %d:[%s]\n",
57 | err.Code(), err.Message()))
58 | }
59 |
60 | //Call the server
61 | if _, err := ac.TpCall(svc, buf, 0); nil != err {
62 | MErrorCode = err.Code()
63 | return errors.New(err.Error())
64 | }
65 |
66 | testdata, err = buf.BGetByteArr(u.T_CARRAY_FLD, 0)
67 |
68 | if nil != err {
69 | fmt.Printf("! Failed to get rsp: ATMI Error %d:[%s]\n",
70 | err.Code(), err.Message())
71 | return errors.New(fmt.Sprintf("! Failed to get rsp: ATMI Error %d:[%s]\n",
72 | err.Code(), err.Message()))
73 | }
74 |
75 | for i := 0; i < len(testdata); i++ {
76 | if testdata[i] != byte((i+2)%255) {
77 |
78 | ac.TpLogError("TESTERROR: Error at index %d expected %d got: %d",
79 | i, (i+2)%255, testdata[i])
80 |
81 | return errors.New(fmt.Sprintf("TESTERROR: Error at index %d expected %d got: %d",
82 | i, (i+2)%255, testdata[i]))
83 | }
84 | }
85 | }
86 |
87 | return nil
88 |
89 | }
90 |
91 | //Do the service call with UBF buffer
92 | func UBFCall(ac *atmi.ATMICtx, cmd string, svc string, times string) error {
93 |
94 | nrTimes, _ := strconv.Atoi(times)
95 |
96 | for i := 0; i < nrTimes; i++ {
97 |
98 | buf, err := ac.NewUBF(1024)
99 |
100 | if err != nil {
101 | return errors.New(err.Error())
102 | }
103 |
104 | //Set some field for call
105 | buf.BChg(u.T_CHAR_FLD, 0, "A")
106 | buf.BChg(u.T_SHORT_FLD, 0, "123")
107 | buf.BChg(u.T_LONG_FLD, 0, i)
108 | buf.BChg(u.T_FLOAT_FLD, 0, "1.33")
109 | buf.BChg(u.T_DOUBLE_FLD, 0, "4444.3333")
110 | buf.BChg(u.T_STRING_FLD, 0, "HELLO")
111 | buf.BChg(u.T_CARRAY_FLD, 0, "WORLD")
112 |
113 | //Call the server
114 | if _, err := ac.TpCall(svc, buf, 0); nil != err {
115 | MErrorCode = err.Code()
116 | return errors.New(err.Error())
117 | }
118 |
119 | //Test the response...
120 | stmt := fmt.Sprintf("T_SHORT_2_FLD==123 "+
121 | "&& T_LONG_2_FLD==%d"+
122 | "&& T_CHAR_2_FLD=='A'"+
123 | "&& T_FLOAT_2_FLD==1.33"+
124 | "&& T_DOUBLE_2_FLD==4444.3333"+
125 | "&& T_STRING_2_FLD=='HELLO'"+
126 | "&& T_CARRAY_2_FLD=='WORLD'", i)
127 |
128 | if res, err := buf.BQBoolEv(stmt); !res || nil != err {
129 | if nil != err {
130 | return errors.New(fmt.Sprintf("juerrors: Expression "+
131 | "failed: %s", err.Error()))
132 | } else {
133 | return errors.New("juerrors: Expression is FALSE!: %s")
134 | }
135 | }
136 | }
137 |
138 | return nil
139 | }
140 |
141 | //Call the service with string buffer
142 | func STRINGCall(ac *atmi.ATMICtx, cmd string, svc string, times string) error {
143 |
144 | nrTimes, _ := strconv.Atoi(times)
145 |
146 | for i := 0; i < nrTimes; i++ {
147 |
148 | buf, err := ac.NewString("Hi there!")
149 |
150 | if err != nil {
151 | return errors.New(err.Error())
152 | }
153 |
154 | //Call the server
155 | if _, err := ac.TpCall(svc, buf, 0); nil != err {
156 | MErrorCode = err.Code()
157 | return errors.New(err.Error())
158 | }
159 |
160 | //Test the response...
161 | s := buf.GetString()
162 | exp := "Hello from EnduroX"
163 |
164 | if s != exp {
165 | ac.TpLogError("Expected: [%s] got [%s]", exp, s)
166 | return errors.New(fmt.Sprintf("Expected: [%s] got [%s]",
167 | exp, s))
168 | }
169 |
170 | }
171 |
172 | return nil
173 | }
174 |
175 | //Call the sever with JSON buffer
176 | func JSONCall(ac *atmi.ATMICtx, cmd string, svc string, times string) error {
177 |
178 | nrTimes, _ := strconv.Atoi(times)
179 |
180 | call := "{\"StringField\":\"Hello\", \"NumField\":12345, \"BoolField\":true}"
181 |
182 | for i := 0; i < nrTimes; i++ {
183 |
184 | var msg TestJSONMsg
185 | buf, err := ac.NewJSON([]byte(call))
186 |
187 | if err != nil {
188 | return errors.New(err.Error())
189 | }
190 |
191 | //Call the server
192 | if _, err := ac.TpCall(svc, buf, 0); nil != err {
193 | MErrorCode = err.Code()
194 | return errors.New(err.Error())
195 | }
196 |
197 | jerr := json.Unmarshal(buf.GetJSON(), &msg)
198 | if jerr != nil {
199 | return fmt.Errorf("Unmarshal: %s", jerr.Error())
200 | }
201 |
202 | //Test the response...
203 | if svc == "JSONJE_OK" || svc == "JSONJE_OKNS" {
204 | //Check the normal rsp...
205 |
206 | if msg.StringField2 != "Hello" {
207 | return fmt.Errorf("StringField2 expted [Hello],"+
208 | " got [%s]", msg.StringField2)
209 | }
210 |
211 | if !msg.BoolField2 {
212 | return errors.New("BoolField2 = true")
213 | }
214 |
215 | if msg.NumField2 != 12345 {
216 |
217 | return fmt.Errorf("NumField2 expected [12345],"+
218 | " got [%d]", msg.NumField)
219 | }
220 | }
221 | }
222 |
223 | return nil
224 | }
225 |
226 | func CmpArrays(a []byte, b []byte) bool {
227 | if len(a) != len(b) {
228 | return false
229 | }
230 | for i, v := range a {
231 | if v != b[i] {
232 | return false
233 | }
234 | }
235 | return true
236 | }
237 |
238 | //Carray/RAW/BINARY tests...
239 | //Call the sever with JSON buffer
240 | func CARRAYCall(ac *atmi.ATMICtx, cmd string, svc string, times string) error {
241 |
242 | nrTimes, _ := strconv.Atoi(times)
243 |
244 | for i := 0; i < nrTimes; i++ {
245 |
246 | buf, err := ac.NewCarray([]byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0})
247 |
248 | if err != nil {
249 | return errors.New(err.Error())
250 | }
251 |
252 | //Call the server
253 | if _, err := ac.TpCall(svc, buf, 0); nil != err {
254 | MErrorCode = err.Code()
255 | return errors.New(err.Error())
256 | }
257 | //Test the response...
258 | if !CmpArrays(buf.GetBytes(), []byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}) {
259 | return fmt.Errorf("Carray fail: expected [[]byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}],"+
260 | " got [%x]", buf.GetBytes())
261 | }
262 | }
263 |
264 | return nil
265 | }
266 |
267 | //Call the view with REQUEST1
268 | func VIEWCallREQUEST1(ac *atmi.ATMICtx, cmd string, svc string, times string) error {
269 |
270 | nrTimes, _ := strconv.Atoi(times)
271 |
272 | for i := 0; i < nrTimes; i++ {
273 |
274 | buf, err := ac.NewVIEW("REQUEST1", 0)
275 |
276 | if err != nil {
277 | return errors.New(err.Error())
278 | }
279 |
280 | //Set some values in buffer...
281 | ac.TpAssertEqualPanic(buf.BVChg("tshort1", 0, 5), nil, "Failed to set tshort1")
282 | ac.TpAssertEqualPanic(buf.BVChg("tlong1", 0, 77777), nil, "Failed to set tlong1")
283 | ac.TpAssertEqualPanic(buf.BVChg("tstring1", 1, "INCOMING TEST"), nil, "Failed to set tstring1")
284 |
285 | //Call the server
286 | if _, err := ac.TpCall(svc, buf, 0); nil != err {
287 | MErrorCode = err.Code()
288 | //In this case return error directly...
289 | if cmd == "view_request1_tout" {
290 | return errors.New(err.Error())
291 | }
292 | }
293 |
294 | //The data still must be parsed in!
295 |
296 | //Test the response...
297 | tstring1, errU := buf.BVGetString("tstring1", 0, 0)
298 | ac.TpAssertEqualPanic(errU, nil, "tstring1 must be present")
299 | ac.TpLogInfo("Got string: [%s]", tstring1)
300 | ac.TpAssertEqualPanic(tstring1, "HELLO RESPONSE", "tstring1 must be set "+
301 | "to \"HELLO RESPONSE\"")
302 |
303 | tstring1, errU = buf.BVGetString("tstring1", 1, 0)
304 | ac.TpAssertEqualPanic(errU, nil, "tstring1[1] must be present")
305 | ac.TpAssertEqualPanic(tstring1, "INCOMING TEST", "tstring1[1] must be set"+
306 | " to \"HELLO TESTCL\"")
307 |
308 | tlong1, errU := buf.BVGetInt64("tlong1", 0, 0)
309 | ac.TpAssertEqualPanic(errU, nil, "tlong1[0] must be present")
310 | ac.TpAssertEqualPanic(tlong1, 11111, "tlong1 must be 11111")
311 | }
312 |
313 | if 0 != MErrorCode {
314 | return errors.New("VIEWCallREQUEST1 failed")
315 | } else {
316 | return nil
317 | }
318 |
319 | }
320 |
321 | //Run the listener
322 | func apprun(ac *atmi.ATMICtx) error {
323 |
324 | //Do some work here
325 |
326 | if len(os.Args) != 4 {
327 | return errors.New(fmt.Sprintf("usage: %s ",
328 | os.Args[0]))
329 | }
330 |
331 | cmd := os.Args[1]
332 | svc := os.Args[2]
333 | times := os.Args[3]
334 |
335 | ac.TpLogInfo("Got command: [%s], service: [%s], times: [%s]", cmd, svc, times)
336 |
337 | //These are projection on 01_restin/runtime/conf/restin.ini cases
338 | switch cmd {
339 | case "ubfcall":
340 | return UBFCall(ac, cmd, svc, times)
341 | case "stringcall":
342 | return STRINGCall(ac, cmd, svc, times)
343 | case "jsoncall":
344 | return JSONCall(ac, cmd, svc, times)
345 | case "carraycall":
346 | return CARRAYCall(ac, cmd, svc, times)
347 | case "view_request1", "view_request1_tout":
348 |
349 | return VIEWCallREQUEST1(ac, cmd, svc, times)
350 | case "bigmsg":
351 | return BigMsg(ac, cmd, svc, times)
352 | default:
353 | return errors.New(fmt.Sprintf("Invalid test case: [%s]", cmd))
354 | }
355 |
356 | }
357 |
358 | //Init function
359 | //@param ac ATMI context
360 | //@return error (if erro) or nil
361 | func appinit(ac *atmi.ATMICtx) error {
362 |
363 | if err := ac.TpInit(); err != nil {
364 | return errors.New(err.Error())
365 | }
366 |
367 | return nil
368 | }
369 |
370 | //Un-init & Terminate the application
371 | //@param ac ATMI Context
372 | //@param restCode Return code. atmi.FAIL (-1) or atmi.SUCCEED(0)
373 | func unInit(ac *atmi.ATMICtx, retCode int) {
374 |
375 | ac.TpTerm()
376 | ac.FreeATMICtx()
377 | os.Exit(retCode)
378 | }
379 |
380 | //Cliet process main entry
381 | func main() {
382 |
383 | ac, errA := atmi.NewATMICtx()
384 |
385 | if nil != errA {
386 | fmt.Fprintf(os.Stderr, "Failed to allocate cotnext %d:%s!\n",
387 | errA.Code(), errA.Message())
388 | os.Exit(atmi.FAIL)
389 | }
390 |
391 | if err := appinit(ac); nil != err {
392 | ac.TpLogError("Failed to init: %s", err)
393 | os.Exit(atmi.FAIL)
394 | }
395 |
396 | ac.TpLogWarn("Init complete, processing...")
397 |
398 | if err := apprun(ac); nil != err {
399 | ac.TpLogError("Got error: [%s]", err.Error())
400 | if 0 == MErrorCode {
401 | MErrorCode = atmi.TPESYSTEM
402 | }
403 | unInit(ac, MErrorCode)
404 | }
405 |
406 | unInit(ac, atmi.SUCCEED)
407 | }
408 |
--------------------------------------------------------------------------------
/go/src/tcpgatesv/atmiout.go:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief Enduro/X -> World (OUT) Request handling...
3 | *
4 | * @file atmiout.go
5 | */
6 | /* -----------------------------------------------------------------------------
7 | * Enduro/X Middleware Platform for Distributed Transaction Processing
8 | * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
9 | * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
10 | * This software is released under one of the following licenses:
11 | * AGPL or Mavimax's license for commercial use.
12 | * -----------------------------------------------------------------------------
13 | * AGPL license:
14 | *
15 | * This program is free software; you can redistribute it and/or modify it under
16 | * the terms of the GNU Affero General Public License, version 3 as published
17 | * by the Free Software Foundation;
18 | *
19 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 | * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
22 | * for more details.
23 | *
24 | * You should have received a copy of the GNU Affero General Public License along
25 | * with this program; if not, write to the Free Software Foundation, Inc.,
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 | *
28 | * -----------------------------------------------------------------------------
29 | * A commercial use license is available from Mavimax, Ltd
30 | * contact@mavimax.com
31 | * -----------------------------------------------------------------------------
32 | */
33 | package main
34 |
35 | import (
36 | "exutil"
37 | u "ubftab"
38 |
39 | atmi "github.com/endurox-dev/endurox-go"
40 | )
41 |
42 | //Generate error that connection is not found
43 | //@param buf UBF buffer
44 | //@param id_comp Compiled/composite connection id (can be simple too)
45 | //@param code Error code
46 | //@param messages Customer error message
47 | func GenResponse(ac *atmi.ATMICtx, buf *atmi.TypedUBF, id_comp int64, code int, message string) {
48 |
49 | sz, _ := buf.BSizeof()
50 | ac.TpLogDebug("Allocating: %d", sz)
51 | ac.BInit(buf, sz)
52 |
53 | if id_comp > 0 {
54 | buf.BChg(u.EX_NETCONNID, 0, id_comp)
55 | }
56 |
57 | buf.BChg(u.EX_NERROR_CODE, 0, code)
58 | buf.BChg(u.EX_NERROR_MSG, 0, message)
59 | }
60 |
61 | //Generate error that connection is not found
62 | //@param buf UBF buffer
63 | //@param id_comp Compiled/composite connection id (can be simple too)
64 | //@param code Error code
65 | //@param messages Customer error message
66 | //@return , ATMI Error code ir failure
67 | func GenErrorUBF(ac *atmi.ATMICtx, id_comp int64, code int, message string) (*atmi.TypedUBF, atmi.ATMIError) {
68 |
69 | buf, errA := ac.NewUBF(1024)
70 |
71 | if nil != errA {
72 | ac.TpLogError("Failed to allocate UBF buffer: %s", errA.Message())
73 | return nil, errA
74 | }
75 |
76 | if id_comp > 0 {
77 | buf.BChg(u.EX_NETCONNID, 0, id_comp)
78 | }
79 |
80 | buf.BChg(u.EX_NERROR_CODE, 0, code)
81 | buf.BChg(u.EX_NERROR_MSG, 0, message)
82 |
83 | return buf, nil
84 |
85 | }
86 |
87 | //Dispatcht the XATMI call (in own go routine)
88 | //@param pool XATMI Pool
89 | //@param nr XATMI client number
90 | //@param ctxData Context data for request
91 | //@param buf ATMI buffer with request data
92 | //@param[in] releaseChan should we release channel here?
93 | func XATMIDispatchCall(pool *XATMIPool, nr int, ctxData *atmi.TPSRVCTXDATA,
94 | buf *atmi.TypedUBF, cd int, releaseChan bool) {
95 |
96 | ret := SUCCEED
97 | ac := pool.ctxs[nr]
98 | var connid int64 = 0
99 | var corr string = ""
100 |
101 | defer func() {
102 |
103 | if SUCCEED == ret {
104 | buf.TpLogPrintUBF(atmi.LOG_DEBUG, "Reply with SUCCEED")
105 | ac.TpReturn(atmi.TPSUCCESS, 0, buf, 0)
106 | } else {
107 | buf.TpLogPrintUBF(atmi.LOG_DEBUG, "Reply with FAIL")
108 | ac.TpReturn(atmi.TPFAIL, 0, buf, 0)
109 | }
110 |
111 | //Put back the channel
112 | //!!!! MUST Be last, otherwise while tpreturn completes
113 | //Other thread can take this object, and that makes race condition +
114 | //Corrpuption !!!!
115 | if releaseChan {
116 | pool.freechan <- nr
117 | }
118 | }()
119 |
120 | ac.TpLogInfo("About to restore context data in goroutine...")
121 | ac.TpSrvSetCtxData(ctxData, 0)
122 | ac.TpSrvFreeCtxData(ctxData) //missing bit...
123 |
124 | //Change the buffer owning context
125 | buf.GetBuf().TpSetCtxt(ac)
126 |
127 | //OK so our context have a call, now do something with it
128 |
129 | connid, _ = buf.BGetInt64(u.EX_NETCONNID, 0)
130 | corr, _ = buf.BGetString(u.EX_NETCORR, 0)
131 |
132 | if RR_PERS_ASYNC_INCL_CORR == MReqReply || RR_PERS_CONN_EX2NET == MReqReply {
133 | if GetOpenConnectionCount() > 0 {
134 | //Get the connection to send message to
135 | /* If connection id specified, then get that one.. */
136 | var con *ExCon
137 | var block DataBlock
138 | var errA atmi.ATMIError
139 |
140 | SetupDataBlock(&block)
141 | block.data, errA = buf.BGetByteArr(u.EX_NETDATA, 0)
142 |
143 | if nil != errA {
144 | ac.TpLogError("Missing EX_NETDATA: %s!", errA.Message())
145 | //Reply with failure
146 |
147 | GenResponse(ac, buf, atmi.NEMANDATORY, 0,
148 | "Mandatory field EX_NETDATA missing!")
149 | ret = FAIL
150 | return
151 |
152 | }
153 | ac.TpLogInfo("Waiting for connection...")
154 | if connid == 0 {
155 | con = GetOpenConnection(ac)
156 | } else {
157 | con = GetConnectionByID(ac, connid)
158 | }
159 |
160 | if nil == con {
161 | GenResponse(ac, buf, 0, atmi.NENOCONN,
162 | "No open connections available")
163 | ret = FAIL
164 | return
165 | }
166 |
167 | block.corr = corr
168 | block.atmi_out_conn_id = connid
169 | block.tstamp_sent = exutil.GetEpochMillis()
170 | block.con = con
171 |
172 | //Register in tables (if needed by config)
173 | haveMCorrWaiter := false
174 | if MReqReply == RR_PERS_ASYNC_INCL_CORR {
175 | //Only in asyn mode
176 | //In process can be only in one waiting list
177 | if corr != "" {
178 | ac.TpLogInfo("Adding request to corr table, by "+
179 | "correlator: [%s]", corr)
180 | MCorrWaiterMutex.Lock()
181 | MCorrWaiter[corr] = &block
182 | MCorrWaiterMutex.Unlock()
183 | haveMCorrWaiter = true
184 | }
185 | }
186 |
187 | //If we work on sync way, only one data exchange over
188 | //The single channel, then lets add to id waiter list
189 | haveMConWaiter := false
190 | if MReqReply == RR_PERS_CONN_EX2NET {
191 | ac.TpLogInfo("Adding request to conn table, by "+
192 | "comp_id: [%d]", con.id_comp)
193 | MConWaiterMutex.Lock()
194 | //WARNING! If we have multiple senders! We loose pervious in-progress calls
195 | //Probably needs to introduce some conditionals to waiton particular
196 | //connection.
197 | //Bug #533
198 | //to overcome this issue, may use seqout=1, this will send away
199 | //with single sender.
200 | MConWaiter[con.id_comp] = &block
201 | MConWaiterMutex.Unlock()
202 | haveMConWaiter = true
203 | }
204 |
205 | ac.TpLogWarn("About to send data...")
206 | con.outgoing <- &block
207 |
208 | //If we are in correl or sync mode we need to wait data
209 | //block back...
210 |
211 | if corr != "" || MReqReply == RR_PERS_CONN_EX2NET {
212 | ac.TpLogWarn("Waiting for reply: correl [%s] "+
213 | "req_reply %d", corr, MReqReply)
214 | //Override the reply buffer
215 | //No more checks... as tout should be already generated.
216 | //So it looks like GO does not track
217 | //pointer in the channel...
218 |
219 | buf = <-block.atmi_chan
220 |
221 | //Change the context of the buf back to ours...
222 | buf.Buf.TpSetCtxt(ac)
223 |
224 | //Remove waiter from lists...
225 | ac.TpLogInfo("Got reply back")
226 |
227 | if haveMCorrWaiter {
228 | ac.TpLogInfo("Removing request from corr table, by "+
229 | "correlator: [%s]", corr)
230 | MCorrWaiterMutex.Lock()
231 | delete(MCorrWaiter, corr)
232 | MCorrWaiterMutex.Unlock()
233 | }
234 |
235 | if haveMConWaiter {
236 | ac.TpLogInfo("Request from conn table, by "+
237 | "comp_id: [%d]", con.id_comp)
238 | MConWaiterMutex.Lock()
239 | delete(MConWaiter, con.id_comp)
240 | MConWaiterMutex.Unlock()
241 | }
242 | } else {
243 | //Just approve the call (and remove data
244 | //so that we do not generate extra IPC traffic
245 | buf.BDel(u.EX_NETDATA, 0)
246 | GenResponse(ac, buf, con.id_comp, 0, "SUCCEED")
247 | }
248 | } else {
249 | //Reply - no connection
250 | GenResponse(ac, buf, 0, atmi.NENOCONN,
251 | "No open connections available")
252 | ret = FAIL
253 | return
254 | }
255 | } else if RR_NONPERS_EX2NET == MReqReply {
256 | ac.TpLogInfo("Non persistent mode, one connection per message. " +
257 | "Try to connect")
258 |
259 | //So we are about to open channel, get the connection id
260 | //Add connection to compiled connection list as normal
261 | //get the connection and send stuff away. The connection Handler
262 | //should know already that conn must be closed by req_reply
263 |
264 | var con ExCon
265 | var block DataBlock
266 | var errA atmi.ATMIError
267 |
268 | SetupDataBlock(&block)
269 | block.data, errA = buf.BGetByteArr(u.EX_NETDATA, 0)
270 |
271 | if nil != errA {
272 | ac.TpLogError("Missing EX_NETDATA: %s!", errA.Message())
273 | //Reply with failure
274 |
275 | GenResponse(ac, buf, 0, atmi.NEMANDATORY,
276 | "Mandatory field EX_NETDATA missing!")
277 | ret = FAIL
278 | return
279 |
280 | }
281 |
282 | SetupConnection(&con)
283 | block.corr = corr
284 | block.atmi_out_conn_id = connid
285 | block.tstamp_sent = exutil.GetEpochMillis()
286 |
287 | //1. Prepare connection block
288 | MConnMutex.Lock()
289 | con.id, con.id_stamp, con.id_comp = GetNewConnectionId(ac)
290 |
291 | if con.id == FAIL {
292 | MConnMutex.Unlock()
293 | ac.TpLogError("Failed to get connection id - max reached?")
294 | ret = FAIL
295 | GenResponse(ac, buf, 0, atmi.NELIMIT,
296 | "Max connections reached!")
297 | return
298 | }
299 |
300 | //2. Add to hash
301 |
302 | MConnectionsSimple[con.id] = &con
303 | MConnectionsComp[con.id_comp] = &con
304 | MConnMutex.Unlock()
305 |
306 | block.con = &con
307 |
308 | //3. and spawn the routine...
309 | //Connection did not succeed.
310 | ac.TpLogInfo("About to Dial...")
311 | go GoDial(&con, &block)
312 |
313 | //4. Register conn in list
314 | ac.TpLogInfo("Register the call")
315 | MConWaiterMutex.Lock()
316 | MConWaiter[con.id_comp] = &block
317 | MConWaiterMutex.Unlock()
318 |
319 | //5. Now try to send stuff out?
320 | ac.TpLogInfo("Sending block out...")
321 | con.outgoing <- &block
322 |
323 | //6. Wait for reply
324 | ac.TpLogInfo("Waiting for reply...")
325 | buf = <-block.atmi_chan
326 |
327 | //Change the context of the buf back to ours...
328 | buf.Buf.TpSetCtxt(ac)
329 |
330 | ac.TpLogInfo("Got reply back")
331 | } else {
332 | ac.TpLogError("Unsupported operation - assuming no connection")
333 | //Reply - no connection
334 | buf.BDel(u.EX_NETDATA, 0)
335 | GenResponse(ac, buf, 0, atmi.NENOCONN,
336 | "No open connections available")
337 | ret = FAIL
338 | return
339 | }
340 | }
341 |
342 | //TODO: Allow to broadcast message over all open connections
343 | /* vim: set ts=4 sw=4 et smartindent: */
344 |
--------------------------------------------------------------------------------