Skip to content

Commit 8af7352

Browse files
authored
Merge pull request #258 from nyaruka/simpler_assets
Simpler assets
2 parents b41f3bc + 6f1ac42 commit 8af7352

File tree

11 files changed

+111
-157
lines changed

11 files changed

+111
-157
lines changed

cmd/flowrunner/testdata/default.json

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[
22
{
3-
"type": "field",
3+
"type": "field_set",
44
"url": "http://testserver/assets/field",
55
"content": [
66
{
@@ -28,11 +28,10 @@
2828
"label": "birth Date",
2929
"value_type": "text"
3030
}
31-
],
32-
"is_set": true
31+
]
3332
},
3433
{
35-
"type": "group",
34+
"type": "group_set",
3635
"url": "http://testserver/assets/group",
3736
"content": [
3837
{
@@ -48,11 +47,10 @@
4847
"name": "Males",
4948
"query": "gender = Male"
5049
}
51-
],
52-
"is_set": true
50+
]
5351
},
5452
{
55-
"type": "channel",
53+
"type": "channel_set",
5654
"url": "http://testserver/assets/channel",
5755
"content": [
5856
{
@@ -76,11 +74,10 @@
7674
"schemes": ["facebook"],
7775
"roles": ["send", "receive"]
7876
}
79-
],
80-
"is_set": true
77+
]
8178
},
8279
{
83-
"type": "label",
80+
"type": "label_set",
8481
"url": "http://testserver/assets/label",
8582
"content": [
8683
{
@@ -91,7 +88,6 @@
9188
"uuid": "b017c07a-d35b-4da4-8917-3bf8bff80168",
9289
"name": "Azuay Messages"
9390
}
94-
],
95-
"is_set": true
91+
]
9692
}
9793
]

cmd/flowrunner/testdata/flows/brochure.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,13 @@
9191
}
9292
},
9393
{
94-
"type": "group",
94+
"type": "group_set",
9595
"url": "http://testserver/assets/group",
9696
"content": [
9797
{
9898
"uuid": "7be2f40b-38a0-4b06-9e6d-522dca592cc8",
9999
"name": "Registered Users"
100100
}
101-
],
102-
"is_set": true
101+
]
103102
}
104103
]

cmd/flowrunner/testdata/flows/dynamic_groups.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
}
6565
},
6666
{
67-
"type": "field",
67+
"type": "field_set",
6868
"url": "http://testserver/assets/field",
6969
"content": [
7070
{
@@ -87,11 +87,10 @@
8787
"label": "State",
8888
"value_type": "text"
8989
}
90-
],
91-
"is_set": true
90+
]
9291
},
9392
{
94-
"type": "group",
93+
"type": "group_set",
9594
"url": "http://testserver/assets/group",
9695
"content": [
9796
{
@@ -119,7 +118,6 @@
119118
"name": "MTN Callers",
120119
"query": "tel ~ \"25078\""
121120
}
122-
],
123-
"is_set": true
121+
]
124122
}
125123
]

cmd/flowserver/server_test.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,14 @@ var testFlowMissingGroupAssets = `[
7979
}
8080
},
8181
{
82-
"type": "group",
82+
"type": "group_set",
8383
"url": "http://testserver/assets/group",
8484
"content": [
8585
{
8686
"uuid": "2aad21f6-30b7-42c5-bd7f-1b720c154817",
8787
"name": "Survey Audience"
8888
}
89-
],
90-
"is_set": true
89+
]
9190
}
9291
]`
9392

@@ -166,9 +165,9 @@ var startRequestTemplate = `{
166165
"assets": %s,
167166
"asset_server": {
168167
"type_urls": {
169-
"field": "http://testserver/assets/field",
170-
"flow": "http://testserver/assets/flow",
171-
"group": "http://testserver/assets/group"
168+
"flow": "http://testserver/assets/flow/{uuid}/",
169+
"field_set": "http://testserver/assets/field/",
170+
"group_set": "http://testserver/assets/group/"
172171
}
173172
},
174173
"trigger": {

cmd/flowserver/static/start.json

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,18 @@
2222
}
2323
},
2424
{
25-
"type": "field",
25+
"type": "field_set",
2626
"url": "http://testserver/assets/field",
2727
"content": [
2828
{
2929
"key": "gender",
3030
"label": "Gender",
3131
"value_type": "text"
3232
}
33-
],
34-
"is_set": true
33+
]
3534
},
3635
{
37-
"type": "channel",
36+
"type": "channel_set",
3837
"url": "http://testserver/assets/channel",
3938
"content": [
4039
{
@@ -49,15 +48,14 @@
4948
"receive"
5049
]
5150
}
52-
],
53-
"is_set": true
51+
]
5452
}
5553
],
5654
"asset_server": {
5755
"type_urls": {
58-
"channel": "http://testserver/assets/channel",
59-
"field": "http://testserver/assets/field",
60-
"flow": "http://testserver/assets/flow"
56+
"flow": "http://testserver/assets/flow/{uuid}/",
57+
"channel_set": "http://testserver/assets/channel/",
58+
"field_set": "http://testserver/assets/field/"
6159
}
6260
},
6361
"trigger": {

flows/assets/assets_test.go

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,56 +11,59 @@ import (
1111

1212
func TestAssetCache(t *testing.T) {
1313
server := NewMockAssetServer()
14-
server.MockResponse("http://testserver/assets/label/f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4/", json.RawMessage(`{
14+
server.MockResponse("http://testserver/assets/label/", json.RawMessage(`[{
1515
"uuid": "f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4",
1616
"name": "Spam"
17-
}`))
17+
}]`))
1818
cache := NewAssetCache(100, 10, "testing/1.0")
1919

20-
asset, err := cache.getSetAsset(server, assetType("pizza"))
20+
asset, err := cache.GetAsset(server, assetType("pizza"), "")
2121
assert.EqualError(t, err, "asset type 'pizza' not supported by asset server")
2222

23-
asset, err = cache.getItemAsset(server, assetTypeLabel, "f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4")
23+
asset, err = cache.GetAsset(server, assetTypeLabelSet, "")
2424
assert.NoError(t, err)
25-
assert.Equal(t, server.MockedRequests(), []string{"http://testserver/assets/label/f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4/"})
25+
assert.Equal(t, server.MockedRequests(), []string{"http://testserver/assets/label/"})
2626

27-
label, isLabel := asset.(*flows.Label)
28-
assert.True(t, isLabel, "expecting label but got something of type %s", reflect.TypeOf(asset))
29-
assert.Equal(t, flows.LabelUUID("f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4"), label.UUID())
30-
assert.Equal(t, "Spam", label.Name())
27+
labelSet, isLabelSet := asset.(*flows.LabelSet)
28+
assert.True(t, isLabelSet, "expecting label set but got something of type %s", reflect.TypeOf(asset))
29+
assert.NotNil(t, labelSet.FindByName("Spam"))
3130

3231
// check that we can refetch without making another server request
33-
asset, err = cache.getItemAsset(server, assetTypeLabel, "f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4")
32+
asset, err = cache.GetAsset(server, assetTypeLabelSet, "")
3433
assert.NoError(t, err)
35-
assert.Equal(t, server.MockedRequests(), []string{"http://testserver/assets/label/f2a3e00c-e86a-4282-a9e8-bb2275e1b9a4/"})
34+
assert.Equal(t, server.MockedRequests(), []string{"http://testserver/assets/label/"})
3635
}
3736

3837
func TestAssetServer(t *testing.T) {
3938
server := NewMockAssetServer()
40-
server.MockResponse("http://testserver/assets/group/2aad21f6-30b7-42c5-bd7f-1b720c154817/", json.RawMessage(`{
41-
"uuid": "2aad21f6-30b7-42c5-bd7f-1b720c154817",
39+
server.MockResponse("http://testserver/assets/group/", json.RawMessage(`[{
40+
"uuid": "da310302-2340-4cee-b5bb-5ee37a24a122",
4241
"name": "Survey Audience"
42+
}]`))
43+
server.MockResponse("http://testserver/assets/flow/2aad21f6-30b7-42c5-bd7f-1b720c154817/", json.RawMessage(`{
44+
"uuid": "2aad21f6-30b7-42c5-bd7f-1b720c154817",
45+
"name": "Registration",
46+
"nodes": []
4347
}`))
4448

45-
url, err := server.getSetAssetURL(assetType("pizza"))
49+
url, err := server.getAssetURL(assetType("pizza"), "")
4650
assert.EqualError(t, err, "asset type 'pizza' not supported by asset server")
4751

48-
url, err = server.getSetAssetURL(assetTypeGroup)
52+
url, err = server.getAssetURL(assetTypeGroupSet, "")
4953
assert.NoError(t, err)
5054
assert.Equal(t, "http://testserver/assets/group/", url)
5155

52-
url, err = server.getItemAssetURL(assetTypeGroup, "2aad21f6-30b7-42c5-bd7f-1b720c154817")
56+
url, err = server.getAssetURL(assetTypeFlow, "2aad21f6-30b7-42c5-bd7f-1b720c154817")
5357
assert.NoError(t, err)
54-
assert.Equal(t, "http://testserver/assets/group/2aad21f6-30b7-42c5-bd7f-1b720c154817/", url)
58+
assert.Equal(t, "http://testserver/assets/flow/2aad21f6-30b7-42c5-bd7f-1b720c154817/", url)
5559

56-
asset, err := server.fetchAsset(url, assetTypeGroup, false, "testing/1.0")
60+
asset, err := server.fetchAsset(url, assetTypeFlow, "testing/1.0")
5761
assert.NoError(t, err)
58-
assert.Equal(t, server.mockedRequests, []string{"http://testserver/assets/group/2aad21f6-30b7-42c5-bd7f-1b720c154817/"})
62+
assert.Equal(t, []string{"http://testserver/assets/flow/2aad21f6-30b7-42c5-bd7f-1b720c154817/"}, server.mockedRequests)
5963

60-
group, isGroup := asset.(*flows.Group)
61-
assert.True(t, isGroup, "expecting group but got something of type %s", reflect.TypeOf(asset))
62-
assert.Equal(t, flows.GroupUUID("2aad21f6-30b7-42c5-bd7f-1b720c154817"), group.UUID())
63-
assert.Equal(t, "Survey Audience", group.Name())
64+
flow, isFlow := asset.(flows.Flow)
65+
assert.True(t, isFlow, "expecting flow but got something of type %s", reflect.TypeOf(asset))
66+
assert.Equal(t, "Registration", flow.Name())
6467
}
6568

6669
func TestSessionAssets(t *testing.T) {

flows/assets/cache.go

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package assets
33
import (
44
"encoding/json"
55
"fmt"
6-
"strconv"
76
"strings"
87
"sync"
98
"time"
@@ -18,11 +17,11 @@ import (
1817
type assetType string
1918

2019
const (
21-
assetTypeChannel assetType = "channel"
22-
assetTypeField assetType = "field"
20+
assetTypeChannelSet assetType = "channel_set"
21+
assetTypeFieldSet assetType = "field_set"
2322
assetTypeFlow assetType = "flow"
24-
assetTypeGroup assetType = "group"
25-
assetTypeLabel assetType = "label"
23+
assetTypeGroupSet assetType = "group_set"
24+
assetTypeLabelSet assetType = "label_set"
2625
assetTypeLocationHierarchy assetType = "location_hierarchy"
2726
)
2827

@@ -58,28 +57,18 @@ func (c *AssetCache) addAsset(url string, asset interface{}) {
5857
c.cache.Set(c.normalizeURL(url), asset, time.Hour*24)
5958
}
6059

61-
// getItemAsset gets an item asset from the cache if it's there or from the asset server
62-
func (c *AssetCache) getItemAsset(server AssetServer, itemType assetType, uuid string) (interface{}, error) {
63-
url, err := server.getItemAssetURL(itemType, uuid)
60+
// GetAsset gets an asset from the cache if it's there or from the asset server
61+
func (c *AssetCache) GetAsset(server AssetServer, itemType assetType, itemUUID string) (interface{}, error) {
62+
url, err := server.getAssetURL(itemType, itemUUID)
6463
if err != nil {
6564
return nil, err
6665
}
6766

68-
return c.getAsset(url, server, itemType, false)
69-
}
70-
71-
// getSetAsset gets an set asset from the cache if it's there or from the asset server
72-
func (c *AssetCache) getSetAsset(server AssetServer, itemType assetType) (interface{}, error) {
73-
url, err := server.getSetAssetURL(itemType)
74-
if err != nil {
75-
return nil, err
76-
}
77-
78-
return c.getAsset(url, server, itemType, true)
67+
return c.getAsset(url, server, itemType)
7968
}
8069

8170
// gets an asset from the cache if it's there or from the asset server
82-
func (c *AssetCache) getAsset(url string, server AssetServer, itemType assetType, isSet bool) (interface{}, error) {
71+
func (c *AssetCache) getAsset(url string, server AssetServer, itemType assetType) (interface{}, error) {
8372
item := c.cache.Get(c.normalizeURL(url))
8473

8574
// asset was in cache, so just return it
@@ -98,7 +87,7 @@ func (c *AssetCache) getAsset(url string, server AssetServer, itemType assetType
9887
}
9988

10089
// actually fetch the asset from it's URL
101-
fetched, err := server.fetchAsset(url, itemType, isSet, c.fetchUserAgent)
90+
fetched, err := server.fetchAsset(url, itemType, c.fetchUserAgent)
10291
if err != nil {
10392
return nil, err
10493
}
@@ -115,7 +104,6 @@ type assetEnvelope struct {
115104
URL string `json:"url" validate:"required,url"`
116105
ItemType assetType `json:"type" validate:"required"`
117106
Content json.RawMessage `json:"content"`
118-
IsSet bool `json:"is_set"`
119107
}
120108

121109
// Include loads assets from the given raw JSON into the cache
@@ -133,7 +121,7 @@ func (c *AssetCache) Include(data json.RawMessage) error {
133121
}
134122

135123
for _, envelope := range envelopes {
136-
asset, err := readAsset(envelope.Content, envelope.ItemType, envelope.IsSet)
124+
asset, err := readAsset(envelope.Content, envelope.ItemType)
137125
if err != nil {
138126
return fmt.Errorf("unable to read asset[url=%s]: %s", envelope.URL, err)
139127
}
@@ -144,31 +132,23 @@ func (c *AssetCache) Include(data json.RawMessage) error {
144132
}
145133

146134
// reads an asset from the given raw JSON data
147-
func readAsset(data json.RawMessage, itemType assetType, isSet bool) (interface{}, error) {
135+
func readAsset(data json.RawMessage, itemType assetType) (interface{}, error) {
148136
var assetReader func(data json.RawMessage) (interface{}, error)
149137

150-
if itemType == assetTypeLocationHierarchy && !isSet {
138+
if itemType == assetTypeLocationHierarchy {
151139
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadLocationHierarchy(data) }
152-
} else if itemType == assetTypeChannel && !isSet {
153-
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadChannel(data) }
154-
} else if itemType == assetTypeChannel && isSet {
140+
} else if itemType == assetTypeChannelSet {
155141
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadChannelSet(data) }
156-
} else if itemType == assetTypeField && !isSet {
157-
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadField(data) }
158-
} else if itemType == assetTypeField && isSet {
142+
} else if itemType == assetTypeFieldSet {
159143
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadFieldSet(data) }
160-
} else if itemType == assetTypeFlow && !isSet {
144+
} else if itemType == assetTypeFlow {
161145
assetReader = func(data json.RawMessage) (interface{}, error) { return definition.ReadFlow(data) }
162-
} else if itemType == assetTypeGroup && !isSet {
163-
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadGroup(data) }
164-
} else if itemType == assetTypeGroup && isSet {
146+
} else if itemType == assetTypeGroupSet {
165147
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadGroupSet(data) }
166-
} else if itemType == assetTypeLabel && !isSet {
167-
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadLabel(data) }
168-
} else if itemType == assetTypeLabel && isSet {
148+
} else if itemType == assetTypeLabelSet {
169149
assetReader = func(data json.RawMessage) (interface{}, error) { return flows.ReadLabelSet(data) }
170150
} else {
171-
return nil, fmt.Errorf("unsupported asset type: %s (set=%s)", itemType, strconv.FormatBool(isSet))
151+
return nil, fmt.Errorf("unsupported asset type: %s", itemType)
172152
}
173153

174154
return assetReader(data)

0 commit comments

Comments
 (0)