コード例 #1
1
ファイル: lifecycle.go プロジェクト: snikch/api
// SetUp creates the database.
func SetUp(seed string) {
	conf := newConf()

	// Retrieve the original DSN value
	originalDSN := conf.Driver.OpenStr

	// Remove the database name
	conf.Driver.OpenStr = strings.Replace(conf.Driver.OpenStr, "DBNAME", "", -1)
	db, err := sql.Open(conf.Driver.Name, conf.Driver.OpenStr)
	if err != nil {
		log.WithError(fail.Trace(err)).Fatal("Could not open db connection")
	}

	// Create a database for this test.
	dbName := "test_" + seed
	_, err = db.Query("CREATE DATABASE IF NOT EXISTS " + dbName)
	if err != nil {
		log.WithError(fail.Trace(err)).WithField("name", dbName).Fatal("Could not create database")
	}

	// Replace the dsn for Goose's sake with the new database name
	conf.Driver.OpenStr = strings.Replace(originalDSN, "DBNAME", dbName, -1)
	os.Setenv("DATABASE_URL", conf.Driver.OpenStr)

	// Get the migrations to run then run them
	target, err := goose.GetMostRecentDBVersion(conf.MigrationsDir)
	if err != nil {
		log.WithError(fail.Trace(err)).Fatal("Could not get most recent db version")
	}

	if err := goose.RunMigrations(conf, conf.MigrationsDir, target); err != nil {
		log.WithError(fail.Trace(err)).Fatal("Could not run setup migrations")
	}
}
コード例 #2
0
ファイル: lifecycle.go プロジェクト: snikch/api
// TearDown destroys the database.
func TearDown(seed string) {
	conf := newConf()

	// Delete the database entirely.
	dbName := "test_" + seed
	conf.Driver.OpenStr = strings.Replace(conf.Driver.OpenStr, "DBNAME", dbName, -1)
	db, err := sql.Open(conf.Driver.Name, conf.Driver.OpenStr)
	if err != nil {
		log.WithError(fail.Trace(err)).Fatal("Could not open db connection")
	}
	_, err = db.Query("DROP DATABASE IF EXISTS " + dbName)
	if err != nil {
		log.WithError(fail.Trace(err)).WithField("name", dbName).Fatal("Could not drop db")
	}
}
コード例 #3
0
ファイル: lifecycle.go プロジェクト: snikch/api
func newConf() *goose.DBConf {
	file := config.String("BASE_DIR") + config.String("DBCONF_DIR", "db")
	conf, err := goose.NewDBConf(file, "test", "")
	if err != nil {
		log.WithError(fail.Trace(err)).WithField("filename", file).Fatal("Could not create new conf")
	}
	return conf
}
コード例 #4
0
ファイル: sneaker.go プロジェクト: snikch/api
// initSneakerSecrets loads any remote secrets from S3.
func initSneakerSecrets() {
	secrets, err := RemoteSecrets()
	if err != nil {
		log.WithError(err).Fatal("Could not download secrets")
	}
	log.WithField("total", len(secrets)).Info("Found remote secrets")
	for name, value := range secrets {
		log.WithField("key", name).Info("Setting secret")
		os.Setenv(name, string(value))
	}
}
コード例 #5
0
ファイル: http.go プロジェクト: snikch/api
// ServeHTTP implements the http.Handler interface and will record information
// about a request, and log it after the request runs.
func (logger Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Retrieve the last client ip from the RemoteAddr header field.
	clientIP := r.RemoteAddr
	if colon := strings.LastIndex(clientIP, ":"); colon != -1 {
		clientIP = clientIP[:colon]
	}

	// Create an access log record.
	record := &LogRecord{
		ResponseWriter: w,
		ip:             clientIP,
		time:           time.Now(),
		method:         r.Method,
		uri:            r.RequestURI,
		protocol:       r.Proto,
	}

	// Set up a function to run once the request has been served.
	defer func(record *LogRecord, startTime time.Time) {
		// Recover from a panic if possible.
		if recovered := recover(); recovered != nil {
			var err error
			// Ensure we have an error interface.
			if thisErr, ok := recovered.(error); ok {
				err = thisErr
			} else {
				err = fmt.Errorf("%s", recovered)
			}
			if err != nil {
				log.WithError(err).Error("Recovered from panic")
				vc.RespondWithError(w, r, err)
			}
		}
		// Log the response info.
		finishTime := time.Now()
		record.time = finishTime.UTC()
		record.duration = finishTime.Sub(startTime)

		log.WithFields(record.Data()).Infof("")
	}(record, time.Now())

	// Serve the request.
	logger.Handler.ServeHTTP(record, r)
}
コード例 #6
0
ファイル: error.go プロジェクト: snikch/api
// RespondWithError will return an error response with the appropriate message,
// and status codes set.
func RespondWithError(w http.ResponseWriter, r *http.Request, err error) {
	isPublicError := false
	errorResponse := APIError{
		Error: err.Error(),
	}
	code := http.StatusInternalServerError
	if statusErr, ok := err.(StatusError); ok {
		// If we get a status code, this error can be considered a public error.
		isPublicError = true
		code = statusErr.StatusCode()
	}

	if descriptiveErr, ok := err.(DescriptiveError); ok {
		errorResponse.Description = descriptiveErr.ErrorDescription()
	}

	if annotatedErr, ok := err.(AnnotatedError); ok {
		errorResponse.Fields = annotatedErr.ErrorFields()
	}

	w.WriteHeader(code)

	// Now log some information about the failure.
	logData := map[string]interface{}{}
	if structuredLogErr, ok := err.(StructuredLogsError); ok {
		for key, value := range structuredLogErr.LogFields() {
			logData[key] = value
		}
	}
	logData["status"] = code

	if !isPublicError {
		logData["original_error"] = err.Error()
		err = fail.NewPrivate(err)
		errorResponse.Error = err.Error()
	}

	body := DefaultRenderer.RenderError(errorResponse)
	w.Write(body)

	log.WithError(err).WithFields(logrus.Fields(logData)).Error("Returning error response")

}