Skip to content

Commit

Permalink
add comments to exported types and methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ajatprabha committed Jul 2, 2019
1 parent 3b112c5 commit 982cf59
Show file tree
Hide file tree
Showing 22 changed files with 141 additions and 5 deletions.
5 changes: 5 additions & 0 deletions internal/handler/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ import (
)

const (
// ContentLengthHeader is the response header key used to set content length
ContentLengthHeader = "Content-Length"
// CacheControlHeader is the response header key used to set cache controll
CacheControlHeader = "Cache-Control"
// StorageGetErrorKey is the key used while pushing metrics update to statsd
StorageGetErrorKey = "handler.storage.get.error"
// ProcessorErrorKey is the key used while pushing metrics update to statsd
ProcessorErrorKey = "handler.processor.error"
)

// ImageHandler is responsible for fetching the path from the storage backend and processing it if required
func ImageHandler(deps *service.Dependencies) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logger.SugaredWithRequest(r)
Expand Down
1 change: 1 addition & 0 deletions internal/handler/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"
)

// Ping handler is used for health check purpose
func Ping() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
Expand Down
9 changes: 9 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,38 +61,47 @@ func newConfig() *config {
}
}

// Update creates a new instance of the configuration and reads all values again
func Update() {
instance = newConfig()
}

// LogLevel returns the log level for logger from the environment
func LogLevel() string {
return getConfig().logLevel
}

// AppName returns the application name from the environment
func AppName() string {
return getConfig().app.name
}

// AppVersion returns the application version from the environment
func AppVersion() string {
return getConfig().app.version
}

// AppDescription returns the application description from the environment
func AppDescription() string {
return getConfig().app.description
}

// DebugModeEnabled returns the debug mode bool from the environment
func DebugModeEnabled() bool {
return getConfig().debugMode
}

// Port returns the application port to be used from the environment
func Port() int {
return getConfig().port
}

// CacheTime returns the time to set the cache-time in image handler from the environment
func CacheTime() int {
return getConfig().cacheTime
}

// Source returns the source struct after it is initialised from the environment values
func Source() *source {
return &getConfig().source
}
15 changes: 15 additions & 0 deletions pkg/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,41 @@ type app struct {
description string
}

// S3Bucket contains the configuration values for S3 source
type S3Bucket struct {
// Name of the bucket
Name string
// Region of the bucket
Region string
// Access key that should be used to access the bucket
AccessKey string
// Secret key that should be used to access the bucket
SecretKey string
}

// WebFolder contains the configuration for a directory available on the public internet
type WebFolder struct {
// BaseURL that should be appended to the path
// Eg: https://example.com/web-folder/{path} will map to https://host.com/{path}
BaseURL string
}

// Cloudfront contains the configuration for cloudfront which can be used with an S3 bucket
type Cloudfront struct {
// Host is the FQDN for the cloudfront integration on the S3 bucket
Host string
// SecureProtocol designates whether to use http or https protocol for requests
SecureProtocol bool
}

type source struct {
// Kind tells which type of Storage backend should be used
Kind string
// HystrixCommand provides the hystrix config to be used with the source to add resiliency
HystrixCommand storage.HystrixCommand
// Value is and interface which holds the actual kind of the object
Value interface{}
// PathPrefix is used to restrict access to specific paths only via the image proxy
PathPrefix string
}

Expand Down
1 change: 1 addition & 0 deletions pkg/config/viper.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
var viperInstance *viper.Viper
var viperInit sync.Once

// Viper creates a new singleton instance of viper.Viper
func Viper() *viper.Viper {
viperInit.Do(func() {
viperInstance = viper.New()
Expand Down
17 changes: 17 additions & 0 deletions pkg/logger/logger.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package logger wraps some commonly used functions from zap.Logger and zap.SugaredLogger
// and maintains a single instance of the logger
package logger

import (
Expand Down Expand Up @@ -53,51 +55,64 @@ func newLogger() *zap.Logger {
}
}

// Debug logs the message at debug level with additional fields, if any
func Debug(message string, fields ...zap.Field) {
getLogger().Debug(message, fields...)
}

// Debugf allows Sprintf style formatting and logs at debug level
func Debugf(template string, args ...interface{}) {
getSugaredLogger().Debugf(template, args)
}

// Error logs the message at error level and prints stacktrace with additional fields, if any
func Error(message string, fields ...zap.Field) {
getLogger().Error(message, fields...)
}

// Errorf allows Sprintf style formatting, logs at error level and prints stacktrace
func Errorf(template string, args ...interface{}) {
getSugaredLogger().Errorf(template, args...)
}

// Fatal logs the message at fatal level with additional fields, if any and exits
func Fatal(message string, fields ...zap.Field) {
getLogger().Fatal(message, fields...)
}

// Fatalf allows Sprintf style formatting, logs at fatal level and exits
func Fatalf(template string, args ...interface{}) {
getSugaredLogger().Fatalf(template, args)
}

// Info logs the message at info level with additional fields, if any
func Info(message string, fields ...zap.Field) {
getLogger().Info(message, fields...)
}

// Infof allows Sprintf style formatting and logs at info level
func Infof(template string, args ...interface{}) {
getSugaredLogger().Infof(template, args)
}

// Warn logs the message at warn level with additional fields, if any
func Warn(message string, fields ...zap.Field) {
getLogger().Warn(message, fields...)
}

// Warnf allows Sprintf style formatting and logs at warn level
func Warnf(template string, args ...interface{}) {
getSugaredLogger().Warnf(template, args)
}

// AddHook adds func(zapcore.Entry) error) to the logger lifecycle
func AddHook(hook func(zapcore.Entry) error) {
instance = getLogger().WithOptions(zap.Hooks(hook))
sugarInstance = instance.Sugar()
}

// WithRequest takes in a http.Request and logs the message with request's Method, Host and Path
// and returns zap.logger
func WithRequest(r *http.Request) *zap.Logger {
return getLogger().With(
zap.Any("method", r.Method),
Expand All @@ -106,6 +121,8 @@ func WithRequest(r *http.Request) *zap.Logger {
)
}

// SugaredWithRequest takes in a http.Request and logs the message with request's Method, Host and Path
// and returns zap.SugaredLogger to support Sprintf styled logging
func SugaredWithRequest(r *http.Request) *zap.SugaredLogger {
return getSugaredLogger().With(
zap.Any("method", r.Method),
Expand Down
11 changes: 11 additions & 0 deletions pkg/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,29 @@ package metrics

import "time"

// Type is used to differentiate between the various metrics update options possible
type Type int

const (
// Duration can update a key which requires a time.Duration value
Duration Type = 0
// Gauge can update a key which requires a numeric value
Gauge Type = 1
// Count can update a key which requires simple increment operation for counting occurrences
Count Type = 2
)

// UpdateOption is used to specify the specs for a metrics update operation
type UpdateOption struct {
// Scope can be used to provide extra context to the metrics
Scope string
// Name is the actual key that will be pushed to stats
// format: {StatsdCollectorConfig.Prefix}.{Scope|default}.{Name}
Name string
// Type is used to differentiate between the various metrics update options possible
Type Type
// NumValue holds a float64 value for the update option
NumValue float64
// Duration holds a time.Duration value for the update option
Duration time.Duration
}
3 changes: 2 additions & 1 deletion pkg/metrics/statsd_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type StatsdCollectorConfig struct {
FlushBytes int
}

// InitializeStatsdCollector will start publishing metrics in the form {config.Prefix}.{name}.{updateOption.Name}
// InitializeStatsdCollector will start publishing metrics in the form {config.Prefix}.{updateOption.Scope|default}.{updateOption.Name}
func InitializeStatsdCollector(config *StatsdCollectorConfig) error {
flushBytes := config.FlushBytes
if flushBytes == 0 {
Expand Down Expand Up @@ -64,6 +64,7 @@ func formatter(updateOption UpdateOption) string {
return fmt.Sprintf("%s.%s", scope, strings.Trim(updateOption.Name, "."))
}

// Update takes an UpdateOption and pushes the metrics to the statd client if initialised
func Update(updateOption UpdateOption) {
if instance == nil {
return
Expand Down
10 changes: 10 additions & 0 deletions pkg/processor/constants.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
package processor

// CropPoint specifies which focus point in the image should be considered while cropping
type CropPoint int

const (
// CropTopLeft crops an image with focus point at top-left
CropTopLeft CropPoint = 1
// CropTop crops an image with focus point at top
CropTop CropPoint = 2
// CropTopRight crops an image with focus point at top-right
CropTopRight CropPoint = 3
// CropLeft crops an image with focus point at left
CropLeft CropPoint = 4
// CropCenter crops an image with focus point at center
CropCenter CropPoint = 5
// CropRight crops an image with focus point at right
CropRight CropPoint = 6
// CropBottomLeft crops an image with focus point at bottom-left
CropBottomLeft CropPoint = 7
// CropBottom crops an image with focus point at bottom
CropBottom CropPoint = 8
// CropBottomRight crops an image with focus point at bottom-right
CropBottomRight CropPoint = 9
)
7 changes: 6 additions & 1 deletion pkg/processor/interface.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package processor

// Processor interface for performing operations on image
// Processor interface for performing operations on image bytes
type Processor interface {
// Crop takes an input byte array, width, height and a CropPoint and returns the cropped image bytes or error
Crop(input []byte, width, height int, point CropPoint) ([]byte, error)
// Resize takes an input byte array, width and height and returns the re-sized image bytes or error
Resize(input []byte, width, height int) ([]byte, error)
// Watermark takes an input byte array, overlay byte array and opacity value
// and returns the watermarked image bytes or error
Watermark(base []byte, overlay []byte, opacity uint8) ([]byte, error)
// GrayScale takes an input byte array and returns the grayscaled byte array or error
GrayScale(input []byte) ([]byte, error)
}
6 changes: 6 additions & 0 deletions pkg/processor/native/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
type BildProcessor struct {
}

// Crop takes an input byte array, width, height and a CropPoint and returns the cropped image bytes or error
func (bp *BildProcessor) Crop(input []byte, width, height int, point processor.CropPoint) ([]byte, error) {
img, f, err := bp.decode(input)
if err != nil {
Expand All @@ -44,6 +45,7 @@ func (bp *BildProcessor) Crop(input []byte, width, height int, point processor.C
return bp.encode(img, f)
}

// Resize takes an input byte array, width and height and returns the re-sized image bytes or error
func (bp *BildProcessor) Resize(input []byte, width, height int) ([]byte, error) {
img, f, err := bp.decode(input)
if err != nil {
Expand All @@ -61,6 +63,8 @@ func (bp *BildProcessor) Resize(input []byte, width, height int) ([]byte, error)
return bp.encode(img, f)
}

// Watermark takes an input byte array, overlay byte array and opacity value
// and returns the watermarked image bytes or error
func (bp *BildProcessor) Watermark(base []byte, overlay []byte, opacity uint8) ([]byte, error) {
baseImg, f, err := bp.decode(base)
if err != nil {
Expand Down Expand Up @@ -93,6 +97,7 @@ func (bp *BildProcessor) Watermark(base []byte, overlay []byte, opacity uint8) (
return bp.encode(baseImg, f)
}

// GrayScale takes an input byte array and returns the grayscaled byte array or error
func (bp *BildProcessor) GrayScale(input []byte) ([]byte, error) {
img, f, err := bp.decode(input)
if err != nil {
Expand Down Expand Up @@ -148,6 +153,7 @@ func (bp *BildProcessor) encode(img image.Image, format string) ([]byte, error)
return buff.Bytes(), err
}

// NewBildProcessor creates a new BildProcessor
func NewBildProcessor() *BildProcessor {
return &BildProcessor{}
}
3 changes: 3 additions & 0 deletions pkg/regex/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package regex
import "regexp"

var (
// S3Matcher regex matches against strings [aws|s3] in any case
S3Matcher = regexp.MustCompile("^(?i)aws|s3$")
// CloudfrontMatcher regex matches against string cloudfront in any case
CloudfrontMatcher = regexp.MustCompile("^(?i)cloudfront$")
// WebFolderMatcher regex matches against string webfolder in any case
WebFolderMatcher = regexp.MustCompile("^(?i)webfolder$")
)
4 changes: 4 additions & 0 deletions pkg/router/routes.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package router has the default routes information
package router

import (
Expand All @@ -13,6 +14,9 @@ import (
"github.com/gorilla/mux"
)

// NewRouter takes in handler Dependencies and returns mux.Router with default routes
// and if debug mode is enabled then it also adds pprof routes.
// It also, adds a PathPrefix to the catch all router if config.Source().PathPrefix is set
func NewRouter(deps *service.Dependencies) *mux.Router {
validateDependencies(deps)
r := mux.NewRouter().StrictSlash(true)
Expand Down
4 changes: 4 additions & 0 deletions pkg/server/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import (
"github.com/gojek/darkroom/pkg/logger"
)

// Server struct wraps a http.Handler and the LifeCycleHook
type Server struct {
handler http.Handler
hook *LifeCycleHook
}

// NewServer returns a new Server configurable with Options
func NewServer(opts ...Option) *Server {
s := Server{}
for _, opt := range opts {
Expand All @@ -25,10 +27,12 @@ func NewServer(opts ...Option) *Server {
return &s
}

// AddLifeCycleHook sets the passed LifeCycleHook to the Server struct
func (s *Server) AddLifeCycleHook(hook *LifeCycleHook) {
s.hook = hook
}

// Start is used to start a http.Server and wait for a kill signal to gracefully shutdown the server
func (s *Server) Start() {
logger.Infof("Starting %s server", config.AppName())

Expand Down
Loading

0 comments on commit 982cf59

Please sign in to comment.