Thursday, 2 July 2020

Golang quirks

I often pass a struct to a function, sometimes the structs contain pointers,
then on initialisation, the question is how to do it in the simplest possible way? 
The definition of transactionType is string

    
    purchaseRequest(&merchant.MerchantPurchaseRequest{
        TransactionType: &"21", // <-- want to do this
    })

// but have to do this
txT := merchant.TransactionType("21")
    purchaseRequest(&merchant.MerchantPurchaseRequest{
        TransactionType: &txT, 
    })


https://golang.org/ref/spec#Address_operators 
https://stackoverflow.com/questions/30716354/how-do-i-do-a-literal-int64-in-go/30716481

Tuesday, 25 February 2020

SAP NWRFCSDK Dockerfile with Golang

Here my working dockerfile for running a golang application depending on SAP/gorfc and the SAP Netweaver library

Compile with

GO111MODULE=on CGO_LDFLAGS_ALLOW=.* CGO_CFLAGS_ALLOW=.* CGO_CXXFLAGS_ALLOW=.*  \
CGO_CFLAGS='-I /usr/local/sap/nwrfcsdk/include' \
CGO_LDFLAGS='-L /usr/local/sap/nwrfcsdk/lib'  \
go build -a -o dist/myapp  cmd/main.go


Dockerfile

FROM debian:bullseye-slim

USER root
WORKDIR /app
EXPOSE 8080

COPY dist/myapp /bin
COPY .env /app
COPY nwrfcsdk.conf /etc/ld.so.conf.d/nwrfcsdk.conf
# unpack and install nwrfcsdk
ADD nwrfc750P_3-70002752.tar.gz /usr/local/sap/
RUN mkdir -p /usr/sap/ && ldconfig -v /usr/local/sap/nwrfcsdk/lib    

ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/usr/local/sap/lib"
ENV LD_RUN_PATH=$LD_RUN_PATH:"/usr/local/sap/lib"
ENV SAPNWRFC_HOME="/usr/local/sap/nwrfcsdk"
ENV PATH="${PATH}:/usr/sap/nwrfcsdk/bin"

ENTRYPOINT [ "/bin/myapp" ]

Wednesday, 22 January 2020

My thoughts on using Apache Nifi for serious integration work



Over the years having implemented quite a few file interfaces, with similar goals but different design principles  (at the time best practice), of which the core is file based ETL with flow routing. With the recent project and juniors to train, I gave Nifi a try, partly because it sports a great UI and is fairly simple to hand over to system administrators, with build in authorisations and policy management.

To give some context to my use of the word serious, the recent integration required files to be interfaced from the logistics system to the financial system and then document management system. The weekly export process was running batch exports and produced approximately 2000 files within minutes with about 100k line items in total each line item translates to 3 financial transactions, which the interface had to generate and track until completed.

More about Nifi on the official site https://nifi.apache.org
    Due to the vast library of ready to use processors, it is a great tool for fast POC work or simple flows but.... perhaps my use case of XML file integration between systems supporting SOAP,REST and SAP RFC is an abuse of the intended use, but the user interface quickly became very crowded, with lots of groovy scrips on the operating system level. It soon reminded me of the reason why big business workflows are typically implemented in code, or eventually migrated to code. Point in case, Uber and AirBNB. To say the least, managing failures became a tedious task.

    The good:
    To extend the tool with custom processors java, was quite trivial. In my case I wrapped the JcoSon library to directly interface to SAP ERP. This solution works great.
    The not so great:
    Flows need error paths, a good thing, but handling the errors in a sane way with complex flows is a challenge in the UI.

    In the end I decided to take a micro service approach in gloang, with technologies like docker, minio, cadence, and kubernetes all running on premise, with a simple UI in Vue.js showing file interface status, and some additional data to enable a user to quickly spot failures. Golang is just a great systems language.


    Chipmaster Gear Cutting

      Calculate all the possible gear combinations for the gear selector to cut a 15TPI thread: Imperial TPI C 5 24 20 Imperial TPI ...