8000 pushing demoapp · optimizely/csharp-sdk@3049bae · GitHub
[go: up one dir, main page]

Skip to content

Commit 3049bae

Browse files
committed
pushing demoapp
1 parent e620c08 commit 3049bae

File tree

6 files changed

+334
-1
lines changed

6 files changed

+334
-1
lines changed

DemoConsoleApp/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
5+
</startup>
6+
</configuration>

DemoConsoleApp/DemoConsoleApp.csproj

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{A0EDCE22-EECC-4407-839E-4743A1AF8F51}</ProjectGuid>
8+
<OutputType>Exe</OutputType>
9+
<RootNamespace>DemoConsoleApp</RootNamespace>
10+
<AssemblyName>DemoConsoleApp</AssemblyName>
11+
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
12+
<FileAlignment>512</FileAlignment>
13+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<PlatformTarget>AnyCPU</PlatformTarget>
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<PlatformTarget>AnyCPU</PlatformTarget>
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>bin\Release\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<Reference Include="MurmurHash, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ff7eff5eb27df7b9, processorArchitecture=MSIL">
37+
<HintPath>..\packages\murmurhash-signed.1.0.2\lib\net45\MurmurHash.dll</HintPath>
38+
</Reference>
39+
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
40+
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
41+
</Reference>
42+
<Reference Include="System" />
43+
<Reference Include="System.Core" />
44+
<Reference Include="System.Xml.Linq" />
45+
<Reference Include="System.Data.DataSetExtensions" />
46+
<Reference Include="Microsoft.CSharp" />
47+
<Reference Include="System.Data" />
48+
<Reference Include="System.Net.Http" />
49+
<Reference Include="System.Xml" />
50+
</ItemGroup>
51+
<ItemGroup>
52+
<Compile Include="Program.cs" />
53+
<Compile Include="Properties\AssemblyInfo.cs" />
54+
</ItemGroup>
55+
<ItemGroup>
56+
<None Include="App.config" />
57+
<None Include="packages.config" />
58+
</ItemGroup>
59+
<ItemGroup>
60+
<ProjectReference Include="..\OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj">
61+
<Project>{cfec91c6-b6e5-45d5-97d6-7081b0dc7453}</Project>
62+
<Name>OptimizelySDK.NetStandard20</Name>
63+
</ProjectReference>
64+
</ItemGroup>
65+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
66+
</Project>

DemoConsoleApp/Program.cs

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Net.Http;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Newtonsoft.Json;
8+
using OptimizelySDK;
9+
using OptimizelySDK.Config;
10+
using OptimizelySDK.Entity;
11+
using OptimizelySDK.ErrorHandler;
12+
using OptimizelySDK.Event;
13+
using OptimizelySDK.Logger;
14+
using OptimizelySDK.Notifications;
15+
using OptimizelySDK.Odp;
16+
using OptimizelySDK.OptimizelyDecisions;
17+
18+
namespace DemoConsoleApp
19+
{
20+
class Program
21+
{
22+
private static void FetchAndDecide(OptimizelyUserContext user)
23+
{
24+
//=========================================
25+
// Fetch Qualified Segments + decide
26+
// =========================================
27+
28+
user.FetchQualifiedSegments(); // to test segment options add one or both as argument: ['RESET_CACHE', 'IGNORE_CACHE']
29+
30+
var options = new OptimizelyDecideOption[] { OptimizelyDecideOption.INCLUDE_REASONS };
31+
32+
OptimizelyDecision decision = user.Decide("flag1", options);
33+
string decisionString = JsonConvert.SerializeObject(decision);
34+
Console.WriteLine(" >>> DECISION " + decisionString);
35+
36+
var segments = user.GetQualifiedSegments();
37+
if (segments != null)
38+
{
39+
Console.WriteLine(" >>> SEGMENTS: [{0}]", string.Join(", ", segments));
40+
41+
foreach (string segment in segments)
42+
{
43+
bool isQualified = user.IsQualifiedFor(segment);
44+
Console.WriteLine(" >>> IS QUALIFIED for " + segment + " : " + isQualified);
45+
}
46+
}
47+
else
48+
{
49+
Console.WriteLine(" >>> SEGMENTS: null");
50+
}
51+
}
52+
53+
private static void SendEvent(Optimizely optimizely)
54+
{
55+
56+
var identifiers = new Dictionary<string, string>();
57+
identifiers.Add("fs-user-id", "fs-id-12");
58+
identifiers.Add("'email'", "fs-bash-x@optimizely.com");
59+
60+
// valid case
61+
optimizely.SendOdpEvent("any", "any", identifiers, null);
62+
63+
// // test missing/ empty identifiers should not be allowed
64+
// optimizely.SendOdpEvent("any", "any", null, null);
65+
// optimizely.SendOdpEvent("any", "any", new Dictionary<string, string>(), null);
66+
//
67+
// // test missing/ empty action should not be allowed
68+
// optimizely.SendOdpEvent("", "any", identifiers, null);
69+
// optimizely.SendOdpEvent(null, "any", identifiers, null);
70+
}
71+
72+
static void Main(string[] args)
73+
{
74+
/** ============================================
75+
# CONFIG TYPE 1:
76+
# default config, minimal settings
77+
============================================
78+
"""
79+
TEST THE FOLLOWING:
80+
- test creating user context with regular attributes
81+
- test creating user context with prebuilt segments (no odp list), should get segments back, experiment should evaluate to true, decide response should look correct
82+
- truth table - TBD
83+
- test creating user context with prebuilt segment list, should get back a list of segments, experiment should evaluate to true, decide response should look correct
84+
- may not need truth table test here (check)
85+
- add RESET_CACHE and/or IGNORE_CACHE to fetch qualified segments call and repeat
86+
- test send event
87+
- verify events on ODP event inspector
88+
- in send_event function uncomment lines of code that test missing identifiers and action keys, verify appropriate error is produced
89+
- test audience segments (see spreadsheet
90+
- test implicit/explicit ODP events?
91+
- test integrations (no ODP integration added to project, integration is on, is off)
92+
"""
93+
**/
94+
var optimizely = OptimizelyFactory.NewDefaultInstance("TbrfRLeKvLyWGusqANoeR");
95+
96+
var optimizelyConfig = optimizely.GetOptimizelyConfig();
97+
98+
var attributes = new UserAttributes();
99+
attributes.Add("laptop_os", "mac");
100+
101+
var user = optimizely.CreateUserContext("fs-id-6", attributes);
102+
103+
FetchAndDecide(user);
104+
SendEvent(optimizely);
105+
106+
optimizely.Dispose();
107+
108+
/** ============================================
109+
# CONFIG TYPE 2:
110+
# with ODP integration changed at app.optimizely.com - changed public key or host url
111+
# VALID API key/HOST url- should work, INVALID KEY/URL-should get errors
112+
# ============================================
113+
"""
114+
TEST THE FOLLOWING:
115+
- test the same as in "CONFIG TYPE 1" but use invalid API key or HOST url
116+
- TODO clarify with Jae what to test here !!!
117+
""" **/
118+
/*optimizely = OptimizelyFactory.NewDefaultInstance("TbrfRLeKvLyWGusqANoeR");
119+
120+
attributes = new UserAttributes();
121+
attributes.Add("laptop_os", "mac");
122+
123+
// CASE 1 - REGULAR ATTRIBUTES, NO ODP
124+
user = optimizely.CreateUserContext("user123", attributes);
125+
126+
// CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matehces DOB)
127+
// user = optimizely.CreateUserContext("fs-id-12", attributes);
128+
129+
// CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6
130+
// user = optimizely.CreateUserContext("fs-id-6", attributes);
131+
132+
FetchAndDecide(user);
133+
SendEvent(optimizely);
134+
135+
optimizely.Dispose();*/
136+
137+
/** ============================================
138+
# CONFIG TYPE 3:
139+
# with different ODP configuration options (odpdisabled, segments_cache_size etc)
140+
# ============================================
141+
"""
142+
TEST THE FOLLOWING:
143+
same as in "CONFIG TYPE 1", but add config options to fetch qualified segments function, for example:
144+
odp_disabled
145+
segments_cache_size
146+
segments_cache_timeout_in_secs
147+
odp_segments_cache
148+
odp_segment_manager
149+
odp_event_manager
150+
odp_segment_request_timeout
151+
odp_event_request_timeout
152+
odp_flush_interval
153+
154+
Observe responses and verity the correct behavior.
155+
"""
156+
**/
157+
var logger = new DefaultLogger();
158+
var errorHandler = new DefaultErrorHandler(logger, false);
159+
var notificationCenter = new NotificationCenter();
160+
var builder = new HttpProjectConfigManager.Builder();
161+
var configManager = builder.WithSdkKey("TbrfRLeKvLyWGusqANoeR").
162+
WithLogger(logger).
163+
WithErrorHandler(errorHandler).
164+
WithNotificationCenter(notificationCenter).
165+
Build(false);
166+
var handler = HttpProjectConfigManager.HttpClient.GetHttpClientHandler();
167+
handler.UseProxy = false;
168+
169+
var fetchSegmentHttpClient = new HttpClient(handler);
170+
fetchSegmentHttpClient.Timeout = TimeSpan.FromMilliseconds(10000);
171+
var sendEventHttpClient = new HttpClient(handler);
172+
sendEventHttpClient.Timeout = TimeSpan.FromMilliseconds(10000);
173+
174+
var odpEventApiManager = new OdpEventApiManager(logger, errorHandler, sendEventHttpClient);
175+
var odpSegmentApiManager = new OdpSegmentApiManager(logger, errorHandler, fetchSegmentHttpClient);
176+
177+
var eventManagerBuilder = new OdpEventManager.Builder()
178+
.WithOdpEventApiManager(odpEventApiManager)
179+
.WithFlushInterval(TimeSpan.FromMilliseconds(1));
180+
181+
OdpSegmentManager odpSegmentManager = new OdpSegmentManager(odpSegmentApiManager, cacheSize: 1, itemTimeout: TimeSpan.FromSeconds(10), logger: logger);
182+
183+
bool disableODP = false; // Set this to true to disable odp and false to enable odp, There is no other way to disable odp, like passing any variable.
184+
OdpManager odpManager = null;
185+
if (!disableODP)
186+
{
187+
odpManager = new OdpManager.Builder()
188+
.WithEventManager(eventManagerBuilder.Build())
189+
.WithSegmentManager(odpSegmentManager)
190+
.WithErrorHandler(errorHandler)
191+
.WithLogger(logger)
192+
.Build();
193+
}
194+
optimizely = new Optimizely(configManager, notificationCenter, null, logger, errorHandler, null, null, null, odpManager);
195+
196+
attributes = new UserAttributes();
197+
attributes.Add("laptop_os", "mac");
198+
199+
// CASE 1 - REGULAR ATTRIBUTES, NO ODP
200+
user = optimizely.CreateUserContext("user123", attributes);
201+
202+
// CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matches DOB)
203+
// user = optimizely.CreateUserContext("fs-id-12", attributes);
204+
205+
// CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6
206+
// user = optimizely.CreateUserContext("fs-id-6", attributes);
20 341A 7+
208+
FetchAndDecide(user);
209+
SendEvent(optimizely);
210+
211+
optimizely.Dispose();
212+
213+
Console.ReadLine();
214+
}
215+
216+
217+
}
218+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("DemoConsoleApp")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("DemoConsoleApp")]
13+
[assembly: AssemblyCopyright("Copyright © 2023")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("a0edce22-eecc-4407-839e-4743a1af8f51")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]

DemoConsoleApp/packages.config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="murmurhash-signed" version="1.0.2" targetFramework="net472" />
4+
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
5+
</packages>

OptimizelySDK.sln

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.Net35", "Opti
2929
EndProject
3030
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.Net40", "OptimizelySDK.Net40\OptimizelySDK.Net40.csproj", "{41AFD990-BC81-49E3-BD85-40972BB2C262}"
3131
EndProject
32-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.NetStandard20", "OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj", "{CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}"
32+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OptimizelySDK.NetStandard20", "OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj", "{CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}"
33+
EndProject
34+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoConsoleApp", "DemoConsoleApp\DemoConsoleApp.csproj", "{A0EDCE22-EECC-4407-839E-4743A1AF8F51}"
3335
EndProject
3436
Global
3537
GlobalSection(SolutionConfigurationPlatforms) = preSolution

0 commit comments

Comments
 (0)
0