github.com/jbking/gohan@v0.0.0-20151217002006-b41ccf1c2a96/schema/resource.go (about)

     1  // Copyright (C) 2015 NTT Innovation Institute, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package schema
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  )
    22  
    23  //Tags are additional metadata for resources
    24  type Tags map[string]string // Tags for each resource
    25  
    26  //TODO(nati)_define proper error struct.
    27  // Stop using fmt.Errorf
    28  
    29  //Resource is a instance of resource
    30  type Resource struct {
    31  	parentID   string
    32  	schema     *Schema
    33  	tags       Tags
    34  	properties map[string]interface{}
    35  }
    36  
    37  //ID gets id from resource
    38  func (resource *Resource) ID() string {
    39  	id, _ := resource.properties["id"]
    40  	idString := fmt.Sprint(id)
    41  	return idString
    42  }
    43  
    44  //Get gets property from resource
    45  func (resource *Resource) Get(key string) interface{} {
    46  	return resource.properties[key]
    47  }
    48  
    49  //ParentID get parent id of the resource
    50  func (resource *Resource) ParentID() string {
    51  	return resource.parentID
    52  }
    53  
    54  //SetParentID set parent id of the resource
    55  func (resource *Resource) SetParentID(id string) {
    56  	schema := resource.schema
    57  	if schema.Parent != "" {
    58  		resource.properties[schema.Parent+"_id"] = id
    59  		resource.parentID = id
    60  	}
    61  }
    62  
    63  //Path generate path for this resource
    64  func (resource *Resource) Path() string {
    65  	s := resource.Schema()
    66  	key := s.URL + "/" + resource.ID()
    67  	return key
    68  }
    69  
    70  //Data gets data from resource
    71  func (resource *Resource) Data() map[string]interface{} {
    72  	return resource.properties
    73  }
    74  
    75  //JSONString returns json string of the resource
    76  func (resource *Resource) JSONString() (string, error) {
    77  	bytes, err := json.Marshal(resource.Data())
    78  	return string(bytes), err
    79  }
    80  
    81  //Schema gets schema from resource
    82  func (resource *Resource) Schema() *Schema {
    83  	return resource.schema
    84  }
    85  
    86  //Values returns list of values
    87  func (resource *Resource) Values() []interface{} {
    88  	var values []interface{}
    89  	schema := resource.schema
    90  	data := resource.properties
    91  	for _, attr := range schema.Properties {
    92  		values = append(values, data[attr.ID])
    93  	}
    94  	return values
    95  }
    96  
    97  //NewResource is a constructor for a resource
    98  func NewResource(schema *Schema, properties map[string]interface{}) (*Resource, error) {
    99  	resource := &Resource{
   100  		schema:     schema,
   101  		properties: properties,
   102  	}
   103  	resource.tags = make(Tags)
   104  	if schema.Parent != "" {
   105  		parentID, ok := properties[schema.Parent+"_id"]
   106  		if ok {
   107  			parentIDStr, _ := parentID.(string)
   108  			resource.SetParentID(parentIDStr)
   109  		}
   110  	}
   111  	return resource, nil
   112  }
   113  
   114  //String return string form representation
   115  func (resource *Resource) String() string {
   116  	return fmt.Sprintf("%v", resource.properties)
   117  }
   118  
   119  //Update resource data
   120  func (resource *Resource) Update(updateData map[string]interface{}) error {
   121  	data := resource.properties
   122  	err := resource.schema.ValidateOnUpdate(updateData)
   123  	if err != nil {
   124  		return err
   125  	}
   126  	for _, property := range resource.schema.Properties {
   127  		id := property.ID
   128  		if val, ok := updateData[id]; ok {
   129  			data[id] = val
   130  		}
   131  	}
   132  	return nil
   133  }
   134  
   135  //PopulateDefaults Populates not provided data with defaults
   136  func (resource *Resource) PopulateDefaults() error {
   137  	for _, property := range resource.Schema().Properties {
   138  		if _, ok := resource.properties[property.ID]; !ok && property.Default != nil {
   139  			resource.properties[property.ID] = property.Default
   140  		}
   141  	}
   142  	return nil
   143  }