0
Fork 0
mirror of https://github.com/willnorris/imageproxy.git synced 2025-02-03 23:10:17 -05:00
imageproxy/vendor/github.com/PaulARoy/azurestoragecache/azurestoragecache.go
2017-09-09 06:12:15 +00:00

136 lines
3.6 KiB
Go

// Copyright 2017 Paul Roy All rights reserved.
//
// 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 azurestoragecache provides an implementation of httpcache.Cache that
// stores and retrieves data using Azure Storage.
package azurestoragecache // import "github.com/PaulARoy/azurestoragecache"
import (
"bytes"
"crypto/md5"
"encoding/hex"
"io"
"io/ioutil"
"log"
"os"
"strconv"
"github.com/Azure/azure-sdk-for-go/storage"
)
// Cache stores and retrieves data using Azure Storage.
type Cache struct {
// The Azure Blob Storage Client
client storage.BlobStorageClient
// container name to use to store blobs
container string
}
var noLogErrors, _ = strconv.ParseBool(os.Getenv("NO_LOG_AZUREBSCACHE_ERRORS"))
func keyToFilename(key string) string {
h := md5.New()
io.WriteString(h, key)
return hex.EncodeToString(h.Sum(nil))
}
// blob retrieves a storage.Blob reference for the specified key.
func (c *Cache) blob(key string) *storage.Blob {
return c.client.GetContainerReference(c.container).GetBlobReference(key)
}
// Get the cached value with the specified key.
func (c *Cache) Get(key string) (resp []byte, ok bool) {
key = keyToFilename(key)
rdr, err := c.blob(key).Get(nil)
if err != nil {
return []byte{}, false
}
resp, err = ioutil.ReadAll(rdr)
if err != nil {
if !noLogErrors {
log.Printf("azurestoragecache.Get failed: %s", err)
}
}
rdr.Close()
return resp, err == nil
}
// Set the cached value with the specified key.
func (c *Cache) Set(key string, value []byte) {
key = keyToFilename(key)
err := c.blob(key).CreateBlockBlobFromReader(bytes.NewReader(value), nil)
if err != nil {
if !noLogErrors {
log.Printf("azurestoragecache.Set failed: %s", err)
}
return
}
}
// Delete the cached value with the specified key.
func (c *Cache) Delete(key string) {
key = keyToFilename(key)
res, err := c.blob(key).DeleteIfExists(nil)
if !noLogErrors {
log.Printf("azurestoragecache.Delete result: %s", res)
}
if err != nil {
if !noLogErrors {
log.Printf("azurestoragecache.Delete failed: %s", err)
}
}
}
// New returns a new Cache with underlying client for Azure Storage.
//
// accountName and accountKey are the Azure Storage credentials. If either are
// empty, the contents of the environment variables AZURESTORAGE_ACCOUNT_NAME
// and AZURESTORAGE_ACCESS_KEY will be used.
//
// containerName is the container name in which cached values will be stored.
// If not specified, "cache" will be used.
func New(accountName string, accountKey string, containerName string) (*Cache, error) {
if accountName == "" {
accountName = os.Getenv("AZURESTORAGE_ACCOUNT_NAME")
}
if accountKey == "" {
accountKey = os.Getenv("AZURESTORAGE_ACCESS_KEY")
}
if containerName == "" {
containerName = "cache"
}
client, err := storage.NewBasicClient(accountName, accountKey)
if err != nil {
return nil, err
}
cache := Cache{
client: client.GetBlobService(),
container: containerName,
}
_, err = cache.client.GetContainerReference(cache.container).CreateIfNotExists(&storage.CreateContainerOptions{Access: storage.ContainerAccessTypeBlob})
if err != nil {
return nil, err
}
return &cache, nil
}