1package graph 2 3import ( 4 "fmt" 5 6 "github.com/wallix/awless/cloud/properties" 7 "github.com/wallix/awless/cloud/rdf" 8 tstore "github.com/wallix/triplestore" 9) 10 11type Resolver interface { 12 Resolve(snap tstore.RDFGraph) ([]*Resource, error) 13} 14 15type ById struct { 16 Id string 17} 18 19func (r *ById) Resolve(snap tstore.RDFGraph) ([]*Resource, error) { 20 resolver := &ByProperty{Key: properties.ID, Value: r.Id} 21 return resolver.Resolve(snap) 22} 23 24type ByTypeAndProperty struct { 25 Type string 26 Key string 27 Value interface{} 28} 29 30func (r *ByTypeAndProperty) Resolve(snap tstore.RDFGraph) ([]*Resource, error) { 31 var resources []*Resource 32 33 if r.Value == nil { 34 return resources, nil 35 } 36 rdfpropLabel, ok := rdf.Labels[r.Key] 37 if !ok { 38 return resources, fmt.Errorf("resolve by property: undefined property label '%s'", r.Key) 39 } 40 rdfProp, err := rdf.Properties.Get(rdfpropLabel) 41 if err != nil { 42 return resources, fmt.Errorf("resolve by property: %s", err) 43 } 44 obj, err := marshalToRdfObject(r.Value, rdfProp.RdfsDefinedBy, rdfProp.RdfsDataType) 45 if err != nil { 46 return resources, fmt.Errorf("resolve by property: unmarshaling property '%s': %s", r.Key, err) 47 } 48 for _, t := range snap.WithPredObj(rdfpropLabel, obj) { 49 rt, err := resolveResourceType(snap, t.Subject()) 50 if err != nil { 51 return resources, err 52 } 53 if rt == r.Type { 54 r := InitResource(rt, t.Subject()) 55 56 if err := r.unmarshalFullRdf(snap); err != nil { 57 return resources, err 58 } 59 resources = append(resources, r) 60 } 61 } 62 return resources, nil 63} 64 65type ByProperty struct { 66 Key string 67 Value interface{} 68} 69 70func (r *ByProperty) Resolve(snap tstore.RDFGraph) ([]*Resource, error) { 71 var resources []*Resource 72 if r.Value == nil { 73 return resources, nil 74 } 75 rdfpropLabel, ok := rdf.Labels[r.Key] 76 if !ok { 77 return resources, fmt.Errorf("resolve by property: undefined property label '%s'", r.Key) 78 } 79 rdfProp, err := rdf.Properties.Get(rdfpropLabel) 80 if err != nil { 81 return resources, fmt.Errorf("resolve by property: %s", err) 82 } 83 obj, err := marshalToRdfObject(r.Value, rdfProp.RdfsDefinedBy, rdfProp.RdfsDataType) 84 if err != nil { 85 return resources, fmt.Errorf("resolve by property: unmarshaling property '%s': %s", r.Key, err) 86 } 87 for _, t := range snap.WithPredObj(rdfpropLabel, obj) { 88 rt, err := resolveResourceType(snap, t.Subject()) 89 if err != nil { 90 return resources, err 91 } 92 r := InitResource(rt, t.Subject()) 93 94 if err := r.unmarshalFullRdf(snap); err != nil { 95 return resources, err 96 } 97 resources = append(resources, r) 98 } 99 return resources, nil 100} 101 102type And struct { 103 Resolvers []Resolver 104} 105 106func (r *And) Resolve(snap tstore.RDFGraph) (result []*Resource, err error) { 107 if len(r.Resolvers) == 0 { 108 return 109 } 110 result, err = r.Resolvers[0].Resolve(snap) 111 if err != nil { 112 return 113 } 114 gg := NewGraph() 115 if err = gg.AddResource(result...); err != nil { 116 return 117 } 118 for _, resolv := range r.Resolvers { 119 result, err = resolv.Resolve(gg.store.Snapshot()) 120 if err != nil { 121 return 122 } 123 gg = NewGraph() 124 if err = gg.AddResource(result...); err != nil { 125 return 126 } 127 } 128 return 129} 130 131type Or struct { 132 Resolvers []Resolver 133} 134 135func (r *Or) Resolve(snap tstore.RDFGraph) (result []*Resource, err error) { 136 for _, resolv := range r.Resolvers { 137 result, err = resolv.Resolve(snap) 138 if err != nil { 139 return 140 } 141 if len(result) > 0 { 142 return 143 } 144 } 145 return 146} 147 148type ByType struct { 149 Typ string 150} 151 152func (r *ByType) Resolve(snap tstore.RDFGraph) ([]*Resource, error) { 153 var resources []*Resource 154 typ := namespacedResourceType(r.Typ) 155 for _, t := range snap.WithPredObj(rdf.RdfType, tstore.Resource(typ)) { 156 r := InitResource(r.Typ, t.Subject()) 157 err := r.unmarshalFullRdf(snap) 158 if err != nil { 159 return resources, err 160 } 161 resources = append(resources, r) 162 } 163 return resources, nil 164} 165 166type ByTypes struct { 167 Typs []string 168} 169 170func (r *ByTypes) Resolve(snap tstore.RDFGraph) ([]*Resource, error) { 171 var res []*Resource 172 for _, t := range r.Typs { 173 bt := &ByType{t} 174 all, err := bt.Resolve(snap) 175 if err != nil { 176 return res, err 177 } 178 res = append(res, all...) 179 } 180 181 return res, nil 182} 183