github.com/vmware/transport-go@v1.3.4/plank/pkg/server/helpers.go (about)

     1  package server
     2  
     3  import (
     4  	"encoding/json"
     5  	"github.com/vmware/transport-go/bus"
     6  	"github.com/vmware/transport-go/plank/utils"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  // generatePlatformServerConfig is a generic internal method that returns the pointer of a new
    15  // instance of PlatformServerConfig. for an argument it can be passed either *serverConfigFactory
    16  // or *cli.Context which the method will analyze and determine the best way to extract user provided values from it.
    17  func generatePlatformServerConfig(f *serverConfigFactory) (*PlatformServerConfig, error) {
    18  	configFile := f.ConfigFile()
    19  	host := f.Hostname()
    20  	port := f.Port()
    21  	rootDir := f.RootDir()
    22  	static := f.Static()
    23  	shutdownTimeoutInMinutes := f.ShutdownTimeout()
    24  	accessLog := f.AccessLog()
    25  	outputLog := f.OutputLog()
    26  	errorLog := f.ErrorLog()
    27  	debug := f.Debug()
    28  	noBanner := f.NoBanner()
    29  	cert := f.Cert()
    30  	certKey := f.CertKey()
    31  	spaPath := f.SpaPath()
    32  	noFabricBroker := f.NoFabricBroker()
    33  	fabricEndpoint := f.FabricEndpoint()
    34  	topicPrefix := f.TopicPrefix()
    35  	queuePrefix := f.QueuePrefix()
    36  	requestPrefix := f.RequestPrefix()
    37  	requestQueuePrefix := f.RequestQueuePrefix()
    38  	prometheus := f.Prometheus()
    39  	restBridgeTimeout := f.RestBridgeTimeout()
    40  
    41  	// if config file flag is provided, read directly from the file
    42  	if len(configFile) > 0 {
    43  		var serverConfig PlatformServerConfig
    44  		b, err := ioutil.ReadFile(configFile)
    45  		if err != nil {
    46  			return nil, err
    47  		}
    48  		if err = json.Unmarshal(b, &serverConfig); err != nil {
    49  			return nil, err
    50  		}
    51  
    52  		// handle invalid duration by setting it to the default value of 5 minutes
    53  		if serverConfig.ShutdownTimeout <= 0 {
    54  			serverConfig.ShutdownTimeout = 5
    55  		}
    56  
    57  		// handle invalid duration by setting it to the default value of 1 minute
    58  		if serverConfig.RestBridgeTimeout <= 0 {
    59  			serverConfig.RestBridgeTimeout = 1
    60  		}
    61  
    62  		// the raw value from the config.json needs to be multiplied by time.Minute otherwise it's interpreted as nanosecond
    63  		serverConfig.ShutdownTimeout = serverConfig.ShutdownTimeout * time.Minute
    64  
    65  		// the raw value from the config.json needs to be multiplied by time.Minute otherwise it's interpreted as nanosecond
    66  		serverConfig.RestBridgeTimeout = serverConfig.RestBridgeTimeout * time.Minute
    67  
    68  		// convert map of cache control rules of SpaConfig into an array
    69  		if serverConfig.SpaConfig != nil {
    70  			serverConfig.SpaConfig.CollateCacheControlRules()
    71  		}
    72  
    73  		return &serverConfig, nil
    74  	}
    75  
    76  	// handle invalid duration by setting it to the default value of 1 minute
    77  	if restBridgeTimeout <= 0 {
    78  		restBridgeTimeout = 1
    79  	}
    80  
    81  	// handle invalid duration by setting it to the default value of 5 minutes
    82  	if shutdownTimeoutInMinutes <= 0 {
    83  		shutdownTimeoutInMinutes = 5
    84  	}
    85  
    86  	// instantiate a server config
    87  	serverConfig := &PlatformServerConfig{
    88  		Host:            host,
    89  		Port:            port,
    90  		RootDir:         rootDir,
    91  		StaticDir:       static,
    92  		ShutdownTimeout: time.Duration(shutdownTimeoutInMinutes) * time.Minute,
    93  		LogConfig: &utils.LogConfig{
    94  			AccessLog:     accessLog,
    95  			ErrorLog:      errorLog,
    96  			OutputLog:     outputLog,
    97  			Root:          rootDir,
    98  			FormatOptions: &utils.LogFormatOption{},
    99  		},
   100  		Debug:             debug,
   101  		NoBanner:          noBanner,
   102  		EnablePrometheus:  prometheus,
   103  		RestBridgeTimeout: time.Duration(restBridgeTimeout) * time.Minute,
   104  	}
   105  
   106  	if len(certKey) > 0 && len(certKey) > 0 {
   107  		var err error
   108  		certKey, err = filepath.Abs(certKey)
   109  		if err != nil {
   110  			return nil, err
   111  		}
   112  		cert, err = filepath.Abs(cert)
   113  		if err != nil {
   114  			return nil, err
   115  		}
   116  
   117  		serverConfig.TLSCertConfig = &TLSCertConfig{CertFile: cert, KeyFile: certKey}
   118  	}
   119  
   120  	if len(strings.TrimSpace(spaPath)) > 0 {
   121  		var err error
   122  		serverConfig.SpaConfig, err = NewSpaConfig(spaPath)
   123  		if err != nil {
   124  			return nil, err
   125  		}
   126  	}
   127  
   128  	// unless --no-Fabric-broker flag is provided, set up a broker config
   129  	if !noFabricBroker {
   130  		serverConfig.FabricConfig = &FabricBrokerConfig{
   131  			FabricEndpoint: fabricEndpoint,
   132  			EndpointConfig: &bus.EndpointConfig{
   133  				TopicPrefix:           topicPrefix,
   134  				UserQueuePrefix:       queuePrefix,
   135  				AppRequestPrefix:      requestPrefix,
   136  				AppRequestQueuePrefix: requestQueuePrefix,
   137  				Heartbeat:             60000},
   138  		}
   139  	}
   140  
   141  	return serverConfig, nil
   142  }
   143  
   144  // ensureResponseInByteSlice takes body as an interface not knowing whether it is already converted to []byte or not.
   145  // if it is not of []byte type it marshals the payload using json.Marshal. otherwise, the input
   146  // byte slice is returned as-is.
   147  func ensureResponseInByteSlice(body interface{}) (bytes []byte, err error) {
   148  	switch body.(type) {
   149  	case []byte:
   150  		bytes, err = body.([]byte), nil
   151  	default:
   152  		bytes, err = json.Marshal(body)
   153  	}
   154  	return
   155  }
   156  
   157  // sanitizeConfigRootPath takes *PlatformServerConfig, ensures the path specified by RootDir field exists.
   158  // if RootDir is empty then the current working directory will be populated. if for some reason the path
   159  // cannot be accessed it'll cause a panic.
   160  func sanitizeConfigRootPath(config *PlatformServerConfig) {
   161  	if len(config.RootDir) == 0 {
   162  		wd, _ := os.Getwd()
   163  		config.RootDir = wd
   164  	}
   165  
   166  	absRootPath, err := filepath.Abs(config.RootDir)
   167  	if err != nil {
   168  		panic(err)
   169  	}
   170  
   171  	_, err = os.Stat(absRootPath)
   172  	if err != nil {
   173  		panic(err)
   174  	}
   175  
   176  	// once it has been confirmed that the path exists, set config.RootDir to the absolute path
   177  	config.RootDir = absRootPath
   178  }