First read this page, then go to setup.

Amalegeni-WS + Go

There was this itch I had to scratch to access my Oracle databases from within the Go programming language. Available was the go-oci8 driver, but that meant installing the Oracle client libraries, and compiling C-code, etc. Not an attractive path to take.

I thought it easier to modify Amalegeni csae template, wrap it with a webserver, and let Go talk to these webservices.

What is it ?

Glad you asked. You just write this code:

variable vBaseServicePackage= amalegeniws.common;
variable vApplicationExceptionPackage= amalegeniws.common;

package amalegeniws.proc.generated;

bean Country
{
    String iso;
    int    area;
    String countryName;
}

package amalegeniws.proc.generated;

service CountryService extends OracleBaseService 
{

    List<Country> getCountry(String iso)
    <<
        select iso, area_sqkm, country
        from   t_country 
        where  iso like ?||'%'
        and    area_sqkm>0
        order  by 2 desc
    >>
    test 
    {{
        iso:="A"
    }}

}

.. and all the rest gets generated for you..

Compile and run

Then use Ant to kick off amalegeni and compile the java code, and finally run the webservice.

ant run

init:

amalegeni:

concatenate:

compile:
    [javac] Compiling 4 source files 

run:
     [java] 2013-08-31 10:11:56.400:INFO:oejs.Server:main: jetty-9.0.4.v20130625
     [java] 2013-08-31 10:11:56.447:INFO:oejs.ServerConnector:main: Started ServerConnector@2d5d9805{HTTP/1.1}{0.0.0.0:8181}

Run the Go-code

go run CountryService.go 

CountryService aka countryservice
--- Executing getCountry() -----------------------------------------------------
{AQ 14000000 Antarctica}
{AU 7686850 Australia}
{AR 2766890 Argentina}
{AO 1246700 Angola}
{AF 647500 Afghanistan}
{AZ 86600 Azerbaijan}
{AT 83858 Austria}
{AE 82880 United Arab Emirates}
{AM 29800 Armenia}
{AL 28748 Albania}
{AN 960 Netherlands Antilles}
{AD 468 Andorra}
{AG 443 Antigua and Barbuda}
{AS 199 American Samoa}
{AW 193 Aruba}
{AI 102 Anguilla}

And that wraps up our Quick tour.

There's more ..

What go code? Oh, the file "CountryService.go", which you'll find in the src/amalegeniws/proc/generated subdirectory:

package main

import (
    "bufio"
    "fmt"
    "io"
    "net/http"
    "strings"
    "strconv"
)


main() {
    pkg:="CountryService"
    fmt.Printf("%s aka %s\n", pkg, strings.ToLower(pkg))


    // CSAE-G06
            iso:="A"

     // CSAE-G08
     fmt.Println( "--- Executing getCountry() ------------------------------------------------------- "[:80])
     for _, sb := range getCountry( iso ) {
         fmt.Printf("%v\n", sb)
     }


}

func create_url(pkg string, method string, param ...string) string {
    // CSAE-G01
    rv := `http://localhost:8181/` + pkg + `.` + method + `(`
    for i, v := range param {
        if i > 0 {
            rv += ","
        }
        rv += `"` + v + `"`
    }
    rv += `)`
    return rv
}

type Country struct {
    Iso string
    Area int64
    CountryName string
}

func tsvToCountry(tsv string) Country {
    // CSAE-G02
    sl:=strings.Split(tsv,"\t")
    var err error
    var iso string
    var area int64
    var countryName string

    if len(sl) > 0 {
        iso  = sl[0]
    }
    if len(sl) > 1 {
        area , err = strconv.ParseInt(sl[1],10,32)
    }
    if len(sl) > 2 {
        countryName  = sl[2]
    }

    if err!=nil {
        fmt.Println("Choked on: " + tsv)
        panic(err)
    }
    return Country{ Iso: iso, Area: area, CountryName: countryName  }
}

func getCountry( iso string ) (collection []Country) {
    // CSAE-G05
    resp, err := http.Get(create_url("CountryService","getCountry",iso  ) )

    if err != nil {
        fmt.Printf("ERROR: %v\n", err)
        return nil
    }
    defer resp.Body.Close()

    r := bufio.NewReader(resp.Body)
    carryOn := true
    for carryOn {
        line, isPrefix, err := r.ReadLine()
        if isPrefix {
            panic("Buffer too small")
        }
        carryOn = (err != io.EOF)
        if err != nil && carryOn {
            fmt.Printf("ERROR: %v\n", err)
        }
        lineStr := string(line)
        if len(strings.TrimSpace(lineStr)) > 0 {
            collection = append(collection, tsvToCountry(lineStr))
        }
    }
    return collection
}

Scenic tour

And if you want to take the scenic tour, you can stop half-way to run that same webservice from your browser:

The parts that make up the whole

I guess by now you've already made this mental picture, about how these parts fit together:

  • Go used http client to talk to the web-server (jetty)
  • The webserver spits out tab-separated output..
  • .. which it fetched (via jdbc) from the Oracle database

Interested?

Okay, then let us show you how to set it up..

Small print

Keywords: amalegeni webserver webservice go golang go-lang go-programming-language oracle

© Willem Moors, 2009 - 2013