Skip to content

Commit 3fe2d2c

Browse files
msohailhussainMichael Ng
authored andcommitted
feat(epmodel): Event Processor datamodel (#171)
1 parent a2727e9 commit 3fe2d2c

File tree

16 files changed

+791
-0
lines changed

16 files changed

+791
-0
lines changed

OptimizelySDK.Net35/OptimizelySDK.Net35.csproj

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,36 @@
227227
<Compile Include="..\OptimizelySDK\Config\FallbackProjectConfigManager.cs">
228228
<Link>Config\FallbackProjectConfigManager.cs</Link>
229229
</Compile>
230+
<Compile Include="..\OptimizelySDK\Event\Entity\ConversionEvent.cs">
231+
<Link>Event\Entity\ConversionEvent.cs</Link>
232+
</Compile>
233+
<Compile Include="..\OptimizelySDK\Event\Entity\Decision.cs">
234+
<Link>Event\Entity\Decision.cs</Link>
235+
</Compile>
236+
<Compile Include="..\OptimizelySDK\Event\Entity\EventBatch.cs">
237+
<Link>Event\Entity\EventBatch.cs</Link>
238+
</Compile>
239+
<Compile Include="..\OptimizelySDK\Event\Entity\EventContext.cs">
240+
<Link>Event\Entity\EventContext.cs</Link>
241+
</Compile>
242+
<Compile Include="..\OptimizelySDK\Event\Entity\ImpressionEvent.cs">
243+
<Link>Event\Entity\ImpressionEvent.cs</Link>
244+
</Compile>
245+
<Compile Include="..\OptimizelySDK\Event\Entity\Snapshot.cs">
246+
<Link>Event\Entity\Snapshot.cs</Link>
247+
</Compile>
248+
<Compile Include="..\OptimizelySDK\Event\Entity\SnapshotEvent.cs">
249+
<Link>Event\Entity\SnapshotEvent.cs</Link>
250+
</Compile>
251+
<Compile Include="..\OptimizelySDK\Event\Entity\UserEvent.cs">
252+
<Link>Event\Entity\UserEvent.cs</Link>
253+
</Compile>
254+
<Compile Include="..\OptimizelySDK\Event\Entity\Visitor.cs">
255+
<Link>Event\Entity\Visitor.cs</Link>
256+
</Compile>
257+
<Compile Include="..\OptimizelySDK\Event\Entity\VisitorAttribute.cs">
258+
<Link>Event\Entity\VisitorAttribute.cs</Link>
259+
</Compile>
230260
</ItemGroup>
231261
<ItemGroup>
232262
<None Include="..\OptimizelySDK\Utils\schema.json">

OptimizelySDK.Net40/OptimizelySDK.Net40.csproj

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,36 @@
237237
<Compile Include="..\OptimizelySDK\OptimizelyFactory.cs">
238238
<Link>OptimizelyFactory.cs</Link>
239239
</Compile>
240+
<Compile Include="..\OptimizelySDK\Event\Entity\ConversionEvent.cs">
241+
<Link>Event\Entity\ConversionEvent.cs</Link>
242+
</Compile>
243+
<Compile Include="..\OptimizelySDK\Event\Entity\Decision.cs">
244+
<Link>Event\Entity\Decision.cs</Link>
245+
</Compile>
246+
<Compile Include="..\OptimizelySDK\Event\Entity\EventBatch.cs">
247+
<Link>Event\Entity\EventBatch.cs</Link>
248+
</Compile>
249+
<Compile Include="..\OptimizelySDK\Event\Entity\EventContext.cs">
250+
<Link>Event\Entity\EventContext.cs</Link>
251+
</Compile>
252+
<Compile Include="..\OptimizelySDK\Event\Entity\ImpressionEvent.cs">
253+
<Link>Event\Entity\ImpressionEvent.cs</Link>
254+
</Compile>
255+
<Compile Include="..\OptimizelySDK\Event\Entity\Snapshot.cs">
256+
<Link>Event\Entity\Snapshot.cs</Link>
257+
</Compile>
258+
<Compile Include="..\OptimizelySDK\Event\Entity\SnapshotEvent.cs">
259+
<Link>Event\Entity\SnapshotEvent.cs</Link>
260+
</Compile>
261+
<Compile Include="..\OptimizelySDK\Event\Entity\UserEvent.cs">
262+
<Link>Event\Entity\UserEvent.cs</Link>
263+
</Compile>
264+
<Compile Include="..\OptimizelySDK\Event\Entity\Visitor.cs">
265+
<Link>Event\Entity\Visitor.cs</Link>
266+
</Compile>
267+
<Compile Include="..\OptimizelySDK\Event\Entity\VisitorAttribute.cs">
268+
<Link>Event\Entity\VisitorAttribute.cs</Link>
269+
</Compile>
240270
</ItemGroup>
241271
<ItemGroup>
242272
<None Include="..\OptimizelySDK\Utils\schema.json">

OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,36 @@
7979
<Compile Include="..\OptimizelySDK\OptimizelyFactory.cs">
8080
<Link>OptimizelyFactory.cs</Link>
8181
</Compile>
82+
<Compile Include="..\OptimizelySDK\Event\Entity\ConversionEvent.cs">
83+
<Link>ConversionEvent.cs</Link>
84+
</Compile>
85+
<Compile Include="..\OptimizelySDK\Event\Entity\EventBatch.cs">
86+
<Link>EventBatch.cs</Link>
87+
</Compile>
88+
<Compile Include="..\OptimizelySDK\Event\Entity\EventContext.cs">
89+
<Link>EventContext.cs</Link>
90+
</Compile>
91+
<Compile Include="..\OptimizelySDK\Event\Entity\ImpressionEvent.cs">
92+
<Link>ImpressionEvent.cs</Link>
93+
</Compile>
94+
<Compile Include="..\OptimizelySDK\Event\Entity\Snapshot.cs">
95+
<Link>Snapshot.cs</Link>
96+
</Compile>
97+
<Compile Include="..\OptimizelySDK\Event\Entity\SnapshotEvent.cs">
98+
<Link>SnapshotEvent.cs</Link>
99+
</Compile>
100+
<Compile Include="..\OptimizelySDK\Event\Entity\UserEvent.cs">
101+
<Link>UserEvent.cs</Link>
102+
</Compile>
103+
<Compile Include="..\OptimizelySDK\Event\Entity\Visitor.cs">
104+
<Link>Visitor.cs</Link>
105+
</Compile>
106+
<Compile Include="..\OptimizelySDK\Event\Entity\VisitorAttribute.cs">
107+
<Link>VisitorAttribute.cs</Link>
108+
</Compile>
109+
<Compile Include="..\OptimizelySDK\Event\Entity\Decision.cs">
110+
<Link>DecisionEvent.cs</Link>
111+
</Compile>
82112
</ItemGroup>
83113
<ItemGroup>
84114
<EmbeddedResource Include="..\OptimizelySDK\Utils\schema.json">
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json.Linq;
4+
using Newtonsoft.Json.Schema;
5+
using NUnit.Framework;
6+
using OptimizelySDK.Entity;
7+
using OptimizelySDK.Event.Entity;
8+
using OptimizelySDK.Utils;
9+
10+
namespace OptimizelySDK.Tests.EventTests
11+
{
12+
[TestFixture]
13+
public class EventEntitiesTest
14+
{
15+
[Test]
16+
public void TestImpressionEventEqualsSerializedPayload()
17+
{
18+
var guid = Guid.NewGuid();
19+
var timeStamp = TestData.SecondsSince1970();
20+
var userId = "TestUserId";
21+
22+
var expectedPayload = new Dictionary<string, object>
23+
{
24+
{ "visitors", new object[]
25+
{
26+
new Dictionary<string, object>()
27+
{
28+
{ "snapshots", new object[]
29+
{
30+
new Dictionary<string, object>
31+
{
32+
{ "decisions", new object[]
33+
{
34+
new Dictionary<string, object>
35+
{
36+
{"campaign_id", "7719770039" },
37+
{"experiment_id", "7716830082" },
38+
{"variation_id", "77210100090" }
39+
}
40+
}
41+
},
42+
{ "events", new object[]
43+
{
44+
new Dictionary<string, object>
45+
{
46+
{"entity_id", "7719770039" },
47+
{"timestamp", timeStamp },
48+
{"uuid", guid },
49+
{"key", "campaign_activated" }
50+
}
51+
}
52+
}
53+
}
54+
}
55+
},
56+
{"attributes", new object[]
57+
{
58+
new Dictionary<string, object>
59+
{
60+
{"entity_id", "7723280020" },
61+
{"key", "device_type" },
62+
{"type", "custom" },
63+
{"value", "iPhone"}
64+
},
65+
new Dictionary<string, object>
66+
{
67+
{"entity_id", ControlAttributes.BOT_FILTERING_ATTRIBUTE},
68+
{"key", ControlAttributes.BOT_FILTERING_ATTRIBUTE},
69+
{"type", "custom" },
70+
{"value", true }
71+
}
72+
}
73+
},
74+
{ "visitor_id", userId }
75+
}
76+
}
77+
},
78+
{"project_id", "7720880029" },
79+
{"account_id", "1592310167" },
80+
{"enrich_decisions", true} ,
81+
{"client_name", "csharp-sdk" },
82+
{"client_version", Optimizely.SDK_VERSION },
83+
{"revision", "15" },
84+
{"anonymize_ip", false}
85+
};
86+
87+
EventBatch.Builder builder = new EventBatch.Builder();
88+
builder.WithAccountId("1592310167")
89+
.WithProjectID("7720880029")
90+
.WithClientVersion(Optimizely.SDK_VERSION)
91+
.WithRevision("15")
92+
.WithClientName("csharp-sdk")
93+
.WithAnonymizeIP(false)
94+
.WithEnrichDecisions(true);
95+
96+
var visitorAttribute1 = new VisitorAttribute(entityId: "7723280020", type: "custom", value: "iPhone", key: "device_type");
97+
var visitorAttribute2 = new VisitorAttribute(entityId: ControlAttributes.BOT_FILTERING_ATTRIBUTE, type: "custom", value: true, key: ControlAttributes.BOT_FILTERING_ATTRIBUTE);
98+
var snapshotEvent = new SnapshotEvent(uuid: guid.ToString(), entityId: "7719770039", key: "campaign_activated",
99+
value: null, revenue: null, timestamp: timeStamp, eventTags: null);
100+
101+
var decision = new Decision("7719770039", "7716830082", "77210100090");
102+
var snapshot = new Snapshot(events: new SnapshotEvent[] { snapshotEvent }, decisions: new Decision[] { decision });
103+
104+
var visitor = new Visitor(
105+
snapshots: new Snapshot[] {
106+
snapshot
107+
},
108+
attributes: new VisitorAttribute[]{
109+
visitorAttribute1, visitorAttribute2},
110+
visitorId: "test_user");
111+
112+
builder.WithVisitors(new Visitor[] { visitor });
113+
114+
EventBatch eventBatch = builder.Build();
115+
// Single Conversion Event
116+
TestData.CompareObjects(expectedPayload, eventBatch);
117+
}
118+
119+
[Test]
120+
public void TestConversionEventEqualsSerializedPayload()
121+
{
122+
123+
var guid = Guid.NewGuid();
124+
var timeStamp = TestData.SecondsSince1970();
125+
126+
var expectdPayload = new Dictionary<string, object>
127+
{
128+
{"client_version", Optimizely.SDK_VERSION},
129+
{"project_id", "111001"},
130+
{"enrich_decisions", true},
131+
{"account_id", "12001"},
132+
{"client_name", "csharp-sdk"},
133+
{"anonymize_ip", false},
134+
{"revision", "2"},
135+
{"visitors", new object[]
136+
{
137+
new Dictionary<string, object>
138+
{
139+
//visitors[0].attributes
140+
{
141+
"attributes", new object[]
142+
{
143+
new Dictionary<string, string>
144+
{
145+
{"entity_id", "111094"},
146+
{"type", "custom"},
147+
{"value", "test_value"},
148+
{"key", "test_attribute"}
149+
}
150+
}
151+
},
152+
//visitors[0].visitor_id
153+
{"visitor_id", "test_user"},
154+
//visitors[0].snapshots
155+
{"snapshots", new object[]
156+
{
157+
//snapshots[0]
158+
new Dictionary<string, object>
159+
{
160+
//snapshots[0].events
161+
{
162+
"events", new object[]
163+
{
164+
new Dictionary<string, object>
165+
{
166+
{"uuid", guid},
167+
{"timestamp", timeStamp},
168+
{"revenue", 4200},
169+
{"value", 1.234},
170+
{"key", "event_with_multiple_running_experiments"},
171+
{"entity_id", "111095"},
172+
{
173+
"tags", new Dictionary<string, object>
174+
{
175+
{"non-revenue", "abc"},
176+
{"revenue", 4200},
177+
{"value", 1.234},
178+
}
179+
}
180+
181+
}
182+
}
183+
}
184+
185+
}
186+
187+
}
188+
}
189+
190+
}
191+
}
192+
193+
}
194+
};
195+
196+
EventBatch.Builder builder = new EventBatch.Builder();
197+
builder.WithAccountId("12001")
198+
.WithProjectID("111001")
199+
.WithClientVersion(Optimizely.SDK_VERSION)
200+
.WithRevision("2")
201+
.WithClientName("csharp-sdk")
202+
.WithAnonymizeIP(false)
203+
.WithEnrichDecisions(true);
204+
205+
var visitorAttribute = new VisitorAttribute(entityId: "111094", type: "custom", value: "test_value", key: "test_attribute");
206+
207+
var snapshotEvent = new SnapshotEvent(uuid: guid.ToString(), entityId: "111095", key: "event_with_multiple_running_experiments",
208+
value: (long?)1.234, revenue: 4200, timestamp: timeStamp, eventTags: new EventTags
209+
{
210+
{"non-revenue", "abc"},
211+
{"revenue", 4200},
212+
{"value", 1.234}
213+
});
214+
215+
var snapshot = new Snapshot(events: new SnapshotEvent[] { snapshotEvent });
216+
217+
var visitor = new Visitor(
218+
snapshots: new Snapshot[] {
219+
snapshot
220+
},
221+
attributes: new VisitorAttribute[]{
222+
visitorAttribute},
223+
visitorId: "test_user");
224+
225+
builder.WithVisitors(new Visitor[] { visitor });
226+
227+
EventBatch eventBatch = builder.Build();
228+
// Single Conversion Event
229+
TestData.CompareObjects(expectdPayload, eventBatch);
230+
}
231+
232+
233+
}
234+
}

OptimizelySDK.Tests/OptimizelySDK.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<Compile Include="ValidEventDispatcher.cs" />
9898
<Compile Include="ConfigTest\TestPollingProjectConfigManager.cs" />
9999
<Compile Include="EntityTests\FeatureVariableTest.cs" />
100+
<Compile Include="EventTests\EventEntitiesTest.cs" />
100101
</ItemGroup>
101102
<ItemGroup>
102103
<Content Include="App.config" />
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2019, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
using OptimizelySDK.Entity;
17+
18+
namespace OptimizelySDK.Event.Entity
19+
{
20+
public class ConversionEvent : UserEvent
21+
{
22+
public string UserId { get; private set; }
23+
public VisitorAttribute[] UserAttributes { get; private set; }
24+
25+
public OptimizelySDK.Entity.Event Event { get; set; }
26+
public EventTags EventTags { get; set; }
27+
}
28+
}

0 commit comments

Comments
 (0)