Move some packages to pkg directory

This commit is contained in:
Arthur Barr
2019-09-17 10:41:24 +01:00
committed by Arthur J Barr
parent 7c59d647f5
commit 8505579b37
29 changed files with 211 additions and 165 deletions

View File

@@ -1,103 +0,0 @@
/*
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package containerruntimelogger
import (
"fmt"
"os"
"runtime"
"strings"
"github.com/ibm-messaging/mq-container/internal/containerruntime"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/internal/user"
)
// LogContainerDetails logs details about the container runtime
func LogContainerDetails(log *logger.Logger) error {
if runtime.GOOS != "linux" {
return fmt.Errorf("Unsupported platform: %v", runtime.GOOS)
}
log.Printf("CPU architecture: %v", runtime.GOARCH)
kv, err := containerruntime.GetKernelVersion()
if err == nil {
log.Printf("Linux kernel version: %v", kv)
}
cr, err := containerruntime.GetContainerRuntime()
if err == nil {
log.Printf("Container runtime: %v", cr)
}
bi, err := containerruntime.GetBaseImage()
if err == nil {
log.Printf("Base image: %v", bi)
}
u, err := user.GetUser()
if err == nil {
if len(u.SupplementalGID) == 0 {
log.Printf("Running as user ID %v (%v) with primary group %v", u.UID, u.Name, u.PrimaryGID)
} else {
log.Printf("Running as user ID %v (%v) with primary group %v, and supplementary groups %v", u.UID, u.Name, u.PrimaryGID, strings.Join(u.SupplementalGID, ","))
}
}
caps, err := containerruntime.GetCapabilities()
capLogged := false
if err == nil {
for k, v := range caps {
if len(v) > 0 {
log.Printf("Capabilities (%s set): %v", strings.ToLower(k), strings.Join(v, ","))
capLogged = true
}
}
if !capLogged {
log.Print("Capabilities: none")
}
} else {
log.Errorf("Error getting capabilities: %v", err)
}
sc, err := containerruntime.GetSeccomp()
if err == nil {
log.Printf("seccomp enforcing mode: %v", sc)
}
log.Printf("Process security attributes: %v", containerruntime.GetSecurityAttributes())
m, err := containerruntime.GetMounts()
if err == nil {
if len(m) == 0 {
log.Print("No volume detected. Persistent messages may be lost")
} else {
for mountPoint, fsType := range m {
log.Printf("Detected '%v' volume mounted to %v", fsType, mountPoint)
if !containerruntime.SupportedFilesystem(fsType) {
return fmt.Errorf("%v uses unsupported filesystem type: %v", mountPoint, fsType)
}
}
}
}
// For a multi-instance queue manager - check all required mounts exist & validate filesystem type
if os.Getenv("MQ_MULTI_INSTANCE") == "true" {
log.Println("Multi-instance queue manager: enabled")
reqMounts := []string{"/mnt/mqm", "/mnt/mqm-log", "/mnt/mqm-data"}
for _, mountPoint := range reqMounts {
if fsType, ok := m[mountPoint]; ok {
if !containerruntime.ValidMultiInstanceFilesystem(fsType) {
return fmt.Errorf("%v uses filesystem type '%v' which is invalid for a multi-instance queue manager", mountPoint, fsType)
}
} else {
return fmt.Errorf("Missing required mount '%v' for a multi-instance queue manager", mountPoint)
}
}
}
return nil
}

View File

@@ -1,165 +0,0 @@
/*
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package logger provides utility functions for logging purposes
package logger
import (
"encoding/json"
"fmt"
"io"
"os"
"os/user"
"strconv"
"sync"
"time"
)
// timestampFormat matches the format used by MQ messages (includes milliseconds)
const timestampFormat string = "2006-01-02T15:04:05.000Z07:00"
const debugLevel string = "DEBUG"
const infoLevel string = "INFO"
const errorLevel string = "ERROR"
// A Logger is used to log messages to stdout
type Logger struct {
mutex sync.Mutex
writer io.Writer
debug bool
json bool
processName string
pid string
serverName string
host string
userName string
}
// NewLogger creates a new logger
func NewLogger(writer io.Writer, debug bool, json bool, serverName string) (*Logger, error) {
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
// This can fail because the container's running as a random UID which
// is not known by the OS. We don't want this to break the logging
// entirely, so just use a blank user name.
user, err := user.Current()
userName := ""
if err == nil {
userName = user.Username
}
return &Logger{
mutex: sync.Mutex{},
writer: writer,
debug: debug,
json: json,
processName: os.Args[0],
pid: strconv.Itoa(os.Getpid()),
serverName: serverName,
host: hostname,
userName: userName,
}, nil
}
func (l *Logger) format(entry map[string]interface{}) (string, error) {
if l.json {
b, err := json.Marshal(entry)
if err != nil {
return "", err
}
return string(b), err
}
return fmt.Sprintf("%v %v\n", entry["ibm_datetime"], entry["message"]), nil
}
// log logs a message at the specified level. The message is enriched with
// additional fields.
func (l *Logger) log(level string, msg string) {
t := time.Now()
entry := map[string]interface{}{
"message": fmt.Sprint(msg),
"ibm_datetime": t.Format(timestampFormat),
"loglevel": level,
"host": l.host,
"ibm_serverName": l.serverName,
"ibm_processName": l.processName,
"ibm_processId": l.pid,
"ibm_userName": l.userName,
"type": "mq_containerlog",
}
s, err := l.format(entry)
l.mutex.Lock()
if err != nil {
// TODO: Fix this
fmt.Println(err)
}
if l.json {
fmt.Fprintln(l.writer, s)
} else {
fmt.Fprint(l.writer, s)
}
l.mutex.Unlock()
}
// Debug logs a line as debug
func (l *Logger) Debug(args ...interface{}) {
if l.debug {
l.log(debugLevel, fmt.Sprint(args...))
}
}
// Debugf logs a line as debug using format specifiers
func (l *Logger) Debugf(format string, args ...interface{}) {
if l.debug {
l.log(debugLevel, fmt.Sprintf(format, args...))
}
}
// Print logs a message as info
func (l *Logger) Print(args ...interface{}) {
l.log(infoLevel, fmt.Sprint(args...))
}
// Println logs a message
func (l *Logger) Println(args ...interface{}) {
l.Print(args...)
}
// Printf logs a message as info using format specifiers
func (l *Logger) Printf(format string, args ...interface{}) {
l.log(infoLevel, fmt.Sprintf(format, args...))
}
// PrintString logs a string as info
func (l *Logger) PrintString(msg string) {
l.log(infoLevel, msg)
}
// Errorf logs a message as error
func (l *Logger) Error(args ...interface{}) {
l.log(errorLevel, fmt.Sprint(args...))
}
// Errorf logs a message as error using format specifiers
func (l *Logger) Errorf(format string, args ...interface{}) {
l.log(errorLevel, fmt.Sprintf(format, args...))
}
// Fatalf logs a message as fatal using format specifiers
// TODO: Remove this
func (l *Logger) Fatalf(format string, args ...interface{}) {
l.log("FATAL", fmt.Sprintf(format, args...))
}

View File

@@ -1,55 +0,0 @@
/*
© Copyright IBM Corporation 2018
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package logger
import (
"bytes"
"encoding/json"
"strings"
"testing"
)
func TestJSONLogger(t *testing.T) {
buf := new(bytes.Buffer)
l, err := NewLogger(buf, true, true, t.Name())
if err != nil {
t.Fatal(err)
}
s := "Hello world"
l.Print(s)
var e map[string]interface{}
err = json.Unmarshal([]byte(buf.String()), &e)
if err != nil {
t.Error(err)
}
if s != e["message"] {
t.Errorf("Expected JSON to contain message=%v; got %v", s, buf.String())
}
}
func TestSimpleLogger(t *testing.T) {
buf := new(bytes.Buffer)
l, err := NewLogger(buf, true, false, t.Name())
if err != nil {
t.Fatal(err)
}
s := "Hello world"
l.Print(s)
if !strings.Contains(buf.String(), s) {
t.Errorf("Expected log output to contain %v; got %v", s, buf.String())
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ limitations under the License.
package metrics
import (
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/prometheus/client_golang/prometheus"
)

View File

@@ -23,7 +23,7 @@ import (
"net/http"
"time"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-container/internal/ready"
"github.com/prometheus/client_golang/prometheus"
)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import (
"strings"
"time"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-golang/ibmmq"
"github.com/ibm-messaging/mq-golang/mqmetric"
)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ import (
"os"
"testing"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-golang/mqmetric"
)

View File

@@ -1,5 +0,0 @@
QueueManager:
Name=foo
Directory=foo
Prefix=/var/mqm
InstallationName=Installation1

View File

@@ -1,5 +0,0 @@
QueueManager:
Name=a/b
Directory=a&b
Prefix=/var/mqm
InstallationName=Installation1

View File

@@ -1,5 +0,0 @@
QueueManager:
Name=..
Directory=!!
Prefix=/var/mqm
InstallationName=Installation1

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/
// Package mqini provides information about queue managers
package mqini
package mqinimerge
import (
"bufio"
@@ -27,92 +27,35 @@ import (
"regexp"
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/pkg/mqini"
)
// QueueManager describe high-level configuration information for a queue manager
type QueueManager struct {
Name string
Prefix string
Directory string
DataPath string
InstallationName string
}
var qmgrDir string
var stanzasQMINI []string
var stanzasMQATINI []string
// getQueueManagerFromStanza parses a queue manager stanza
func getQueueManagerFromStanza(stanza string) (*QueueManager, error) {
scanner := bufio.NewScanner(strings.NewReader(stanza))
qm := QueueManager{}
for scanner.Scan() {
l := scanner.Text()
l = strings.TrimSpace(l)
t := strings.Split(l, "=")
switch t[0] {
case "Name":
qm.Name = t[1]
case "Prefix":
qm.Prefix = t[1]
case "Directory":
qm.Directory = t[1]
case "DataPath":
qm.DataPath = t[1]
case "InstallationName":
qm.InstallationName = t[1]
}
}
return &qm, scanner.Err()
}
// GetQueueManager returns queue manager configuration information
func GetQueueManager(name string) (*QueueManager, error) {
// dspmqinf essentially returns a subset of mqs.ini, but it's simpler to parse
out, _, err := command.Run("dspmqinf", "-o", "stanza", name)
if err != nil {
return nil, err
}
return getQueueManagerFromStanza(out)
}
// GetErrorLogDirectory returns the directory holding the error logs for the
// specified queue manager
func GetErrorLogDirectory(qm *QueueManager) string {
if qm.DataPath != "" {
return filepath.Join(qm.DataPath, "errors")
}
return filepath.Join(qm.Prefix, "qmgrs", qm.Directory, "errors")
}
//AddStanzas Reads supplied mq ini configuration files and updates the stanzas
//into queue manager's ini configuration files.
// AddStanzas reads supplied MQ INI configuration files and updates the stanzas
// in the queue manager's INI configuration files.
func AddStanzas(qmname string) error {
//find the qmgr directory.
qm, err := GetQueueManager(qmname)
// Find the qmgr directory.
qm, err := mqini.GetQueueManager(qmname)
if err != nil {
return err
}
qmgrDir = filepath.Join(qm.Prefix, "qmgrs", qm.Directory)
if qm.DataPath != "" {
qmgrDir = qm.DataPath
}
//Find the users ini configuration file
qmgrDir = mqini.GetDataDirectory(qm)
// Find the users ini configuration file
files, err := getIniFileList()
if err != nil {
return err
}
if len(files) > 1 {
msg := fmt.Sprintf("[ %v ]", files)
return errors.New("Only a single ini file can be provided. Following ini files are found:" + msg)
return errors.New("Only a single INI file can be provided. Following INI files were found:" + msg)
}
if len(files) == 0 {
//no ini file update required.
// No INI file update required.
return nil
}
@@ -125,10 +68,10 @@ func AddStanzas(qmname string) error {
return nil
}
//Prepare a list of all supported stanzas
// Prepare a list of all supported stanzas
PopulateAllAvailableStanzas()
//Update the qmgr ini file with user config.
// Update the qmgr ini file with user config.
qmConfig, atConfig, err := PrepareConfigStanzasToWrite(userconfig)
if err != nil {
return err
@@ -141,7 +84,7 @@ func AddStanzas(qmname string) error {
return nil
}
// PopulateAllAvailableStanzas initializes the ini stanzas prescribed by mq specification.
// PopulateAllAvailableStanzas initializes the INI stanzas prescribed by MQ specification.
func PopulateAllAvailableStanzas() {
stanzasQMINI = []string{"ExitPath",
"Log",
@@ -166,9 +109,8 @@ func PopulateAllAvailableStanzas() {
stanzasMQATINI = []string{"AllActivityTrace", "ApplicationTrace"}
}
// getIniFileList Checks for the user supplied ini file in /etc/mqm directory.
// getIniFileList checks for the user supplied INI file in `/etc/mqm` directory.
func getIniFileList() ([]string, error) {
fileList := []string{}
err := filepath.Walk("/etc/mqm", func(path string, f os.FileInfo, err error) error {
if strings.HasSuffix(path, ".ini") {
@@ -182,10 +124,9 @@ func getIniFileList() ([]string, error) {
return fileList, nil
}
//PrepareConfigStanzasToWrite Reads through the user supplied ini config file and prepares list of
//updates to be written into corresponding mq ini files (qm.ini and/or mqat.ini files.)
// PrepareConfigStanzasToWrite Reads through the user supplied INI config file and prepares list of
// updates to be written into corresponding mq ini files (qm.ini and/or mqat.ini files)
func PrepareConfigStanzasToWrite(userconfig string) (string, string, error) {
var qminiConfigStr string
var mqatiniConfigStr string
@@ -215,13 +156,13 @@ func PrepareConfigStanzasToWrite(userconfig string) (string, string, error) {
consumeToMerge := false
var stanza string
//read through the user file and prepare what we want.
// Read through the user file and prepare what we want.
for scanner.Scan() {
if strings.Contains(scanner.Text(), ":") {
consumetoAppend = false
consumeToMerge = false
stanza = scanner.Text()
//check if this stanza exists in the qm.ini/mqat.ini files
// Check if this stanza exists in the qm.ini/mqat.ini files
if strings.Contains(qminiConfigStr, stanza) ||
(strings.Contains(mqatiniConfigStr, stanza) && !(strings.Contains(stanza, "ApplicationTrace"))) {
consumeToMerge = true
@@ -253,7 +194,7 @@ func PrepareConfigStanzasToWrite(userconfig string) (string, string, error) {
}
}
//merge if stanza exits.
// Merge if stanza exits
if len(stanzaListMerge) > 0 {
for key := range stanzaListMerge {
toWrite, filename := ValidateStanzaToWrite(key)
@@ -270,7 +211,7 @@ func PrepareConfigStanzasToWrite(userconfig string) (string, string, error) {
}
}
//append new stanzas.
// Append new stanzas.
if len(stanzaListAppend) > 0 {
for key := range stanzaListAppend {
attrList := stanzaListAppend[key]
@@ -285,7 +226,7 @@ func PrepareConfigStanzasToWrite(userconfig string) (string, string, error) {
return qminiConfigStr, mqatiniConfigStr, nil
}
//ValidateStanzaToWrite Validates stanza to be written and the file it belongs to.
// ValidateStanzaToWrite validates stanza to be written and the file it belongs to.
func ValidateStanzaToWrite(stanza string) (bool, string) {
stanza = strings.TrimSpace(stanza)
if strings.Contains(stanza, ":") {
@@ -301,26 +242,27 @@ func ValidateStanzaToWrite(stanza string) (bool, string) {
}
}
//prepareStanzasToAppend Prepares list of stanzas that are to be appended into qm ini files(qm.ini/mqat.ini)
// prepareStanzasToAppend Prepares list of stanzas that are to be appended into qm ini files(qm.ini/mqat.ini)
func prepareStanzasToAppend(key string, attrList strings.Builder, iniConfig string) string {
newVal := key + "\n" + attrList.String()
iniConfig = iniConfig + newVal
return iniConfig
}
//prepareStanzasToMerge Prepares list of stanzas that are to be updated into qm ini files(qm.ini/mqat.ini)
//These stanzas are already present in mq ini files and their values have to be updated with user supplied ini.
// prepareStanzasToMerge Prepares list of stanzas that are to be updated into qm ini files(qm.ini/mqat.ini)
// These stanzas are already present in mq ini files and their values have to be updated with user supplied ini.
func prepareStanzasToMerge(key string, attrList strings.Builder, iniConfig string) string {
lineScanner := bufio.NewScanner(strings.NewReader(attrList.String()))
lineScanner.Split(bufio.ScanLines)
for lineScanner.Scan() {
attrLine := lineScanner.Text()
keyvalue := strings.Split(attrLine, "=")
//this line present in qm.ini, update value.
// This line present in qm.ini, update value.
if strings.Contains(iniConfig, keyvalue[0]) {
re := regexp.MustCompile(keyvalue[0] + "=.*")
iniConfig = re.ReplaceAllString(iniConfig, attrLine)
} else { //this line not present in qm.ini file, add it.
} else {
// This line not present in qm.ini file, add it.
re := regexp.MustCompile(key)
newVal := key + "\n" + attrLine
iniConfig = re.ReplaceAllString(iniConfig, newVal)
@@ -329,9 +271,8 @@ func prepareStanzasToMerge(key string, attrList strings.Builder, iniConfig strin
return iniConfig
}
//writeConfigStanzas Writes the ini file updates into corresponding mq ini files.
// writeConfigStanzas writes the INI file updates into corresponding mq ini files.
func writeConfigStanzas(qmConfig string, atConfig string) error {
err := ioutil.WriteFile(filepath.Join(qmgrDir, "qm.ini"), []byte(qmConfig), 0644)
if err != nil {
return err

View File

@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mqini
package mqinimerge
import (
"bufio"
@@ -22,49 +22,6 @@ import (
"testing"
)
var getQueueManagerTests = []struct {
file string
name string
prefix string
directory string
errorLogDir string
}{
{"dspmqinf1.txt", "foo", "/var/mqm", "foo", "/var/mqm/qmgrs/foo/errors"},
{"dspmqinf2.txt", "a/b", "/var/mqm", "a&b", "/var/mqm/qmgrs/a&b/errors"},
{"dspmqinf3.txt", "..", "/var/mqm", "!!", "/var/mqm/qmgrs/!!/errors"},
}
func TestGetQueueManager(t *testing.T) {
for _, table := range getQueueManagerTests {
t.Run(table.file, func(t *testing.T) {
b, err := ioutil.ReadFile(table.file)
if err != nil {
t.Fatal(err)
}
qm, err := getQueueManagerFromStanza(string(b))
if err != nil {
t.Fatal(err)
}
t.Logf("%#v", qm)
if qm.Name != table.name {
t.Errorf("Expected name=%v; got %v", table.name, qm.Name)
}
if qm.Prefix != table.prefix {
t.Errorf("Expected prefix=%v; got %v", table.prefix, qm.Prefix)
}
if qm.Directory != table.directory {
t.Errorf("Expected directory=%v; got %v", table.directory, qm.Directory)
}
// Test
d := GetErrorLogDirectory(qm)
if d != table.errorLogDir {
t.Errorf("Expected error log directory=%v; got %v", table.errorLogDir, d)
}
})
}
}
func TestIniFileStanzas(t *testing.T) {
PopulateAllAvailableStanzas()
@@ -87,7 +44,6 @@ func TestIniFileStanzas(t *testing.T) {
}
func TestIniFile1Update(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile("test1qm.ini")
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
@@ -116,7 +72,6 @@ func TestIniFile1Update(t *testing.T) {
}
func TestIniFile2Update(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile("test2qm.ini")
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
@@ -145,7 +100,6 @@ func TestIniFile2Update(t *testing.T) {
}
func TestIniFile3Update(t *testing.T) {
i := 0
iniFileBytes, err := ioutil.ReadFile("test3qm.ini")
if err != nil {
@@ -182,7 +136,6 @@ func TestIniFile3Update(t *testing.T) {
}
func checkReturns(stanza string, isqmini bool, shouldexist bool, t *testing.T) {
exists, filename := ValidateStanzaToWrite(stanza)
if exists != shouldexist {
t.Errorf("Stanza should exist %t but found was %t", shouldexist, exists)

View File

@@ -1,8 +1,8 @@
ApiExitLocal:   
Sequence=1
Function=EntryPoint
Module=/opt/MQOpenTracing/MQOpenTracingExit.so
Name=MQOpenTracingExit
Module=/opt/foo/foo.so
Name=FooExit
Channels:
MQIBindType=FASTPATH
Log:

View File

@@ -23,7 +23,7 @@ import (
"text/template"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
)
// ProcessTemplateFile takes a Go templateFile, and processes it with the

View File

@@ -1,46 +0,0 @@
/*
© Copyright IBM Corporation 2017
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package name contains code to manage the queue manager name
package name
import (
"os"
"regexp"
)
// sanitizeQueueManagerName removes any invalid characters from a queue manager name
func sanitizeQueueManagerName(name string) string {
var re = regexp.MustCompile("[^a-zA-Z0-9._%/]")
return re.ReplaceAllString(name, "")
}
// GetQueueManagerName resolves the queue manager name to use. Resolved from
// either an environment variable, or the hostname.
func GetQueueManagerName() (string, error) {
var name string
var err error
name, ok := os.LookupEnv("MQ_QMGR_NAME")
if !ok || name == "" {
name, err = os.Hostname()
if err != nil {
return "", err
}
name = sanitizeQueueManagerName(name)
}
// TODO: What if the specified env variable is an invalid name?
return name, nil
}

View File

@@ -1,56 +0,0 @@
/*
© Copyright IBM Corporation 2017
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package name
import (
"os"
"testing"
)
var sanitizeTests = []struct {
in string
out string
}{
{"foo", "foo"},
{"foo-0", "foo0"},
{"foo-", "foo"},
{"-foo", "foo"},
{"foo_0", "foo_0"},
}
func TestSanitizeQueueManagerName(t *testing.T) {
for _, table := range sanitizeTests {
s := sanitizeQueueManagerName(table.in)
if s != table.out {
t.Errorf("sanitizeQueueManagerName(%v) - expected %v, got %v", table.in, table.out, s)
}
}
}
func TestGetQueueManagerNameFromEnv(t *testing.T) {
const data string = "foo"
err := os.Setenv("MQ_QMGR_NAME", data)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
n, err := GetQueueManagerName()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if n != data {
t.Errorf("Expected name=%v, got name=%v", data, n)
}
}