8000 [FSSDK-9001] Fix: ODP should be enabled by default when initialized optimizely using OptimizelyFactory by mnoman09 · Pull Request #337 · optimizely/csharp-sdk · GitHub
[go: up one dir, main page]

Skip to content

[FSSDK-9001] Fix: ODP should be enabled by default when initialized optimizely using OptimizelyFactory #337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
pushing demoapp
  • Loading branch information
NomanShoaib committed Mar 17, 2023
commit 3049bae7e25d7d3967f72cad8c87ae5d15cd9af5
6 changes: 6 additions & 0 deletions DemoConsoleApp/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
66 changes: 66 additions & 0 deletions DemoConsoleApp/DemoConsoleApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A0EDCE22-EECC-4407-839E-4743A1AF8F51}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DemoConsoleApp</RootNamespace>
<AssemblyName>DemoConsoleApp</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="MurmurHash, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ff7eff5eb27df7b9, processorArchitecture=MSIL">
<HintPath>..\packages\murmurhash-signed.1.0.2\lib\net45\MurmurHash.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj">
<Project>{cfec91c6-b6e5-45d5-97d6-7081b0dc7453}</Project>
<Name>OptimizelySDK.NetStandard20</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
218 changes: 218 additions & 0 deletions DemoConsoleApp/Program.cs
8000
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using OptimizelySDK;
using OptimizelySDK.Config;
using OptimizelySDK.Entity;
using OptimizelySDK.ErrorHandler;
using OptimizelySDK.Event;
using OptimizelySDK.Logger;
using OptimizelySDK.Notifications;
using OptimizelySDK.Odp;
using OptimizelySDK.OptimizelyDecisions;

namespace DemoConsoleApp
{
class Program
{
private static void FetchAndDecide(OptimizelyUserContext user)
{
//=========================================
// Fetch Qualified Segments + decide
// =========================================

user.FetchQualifiedSegments(); // to test segment options add one or both as argument: ['RESET_CACHE', 'IGNORE_CACHE']

var options = new OptimizelyDecideOption[] { OptimizelyDecideOption.INCLUDE_REASONS };

OptimizelyDecision decision = user.Decide("flag1", options);
string decisionString = JsonConvert.SerializeObject(decision);
Console.WriteLine(" >>> DECISION " + decisionString);

var segments = user.GetQualifiedSegments();
if (segments != null)
{
Console.WriteLine(" >>> SEGMENTS: [{0}]", string.Join(", ", segments));

foreach (string segment in segments)
{
bool isQualified = user.IsQualifiedFor(segment);
Console.WriteLine(" >>> IS QUALIFIED for " + segment + " : " + isQualified);
}
}
else
{
Console.WriteLine(" >>> SEGMENTS: null");
}
}

private static void SendEvent(Optimizely optimizely)
{

var identifiers = new Dictionary<string, string>();
identifiers.Add("fs-user-id", "fs-id-12");
identifiers.Add("'email'", "fs-bash-x@optimizely.com");

// valid case
optimizely.SendOdpEvent("any", "any", identifiers, null);

// // test missing/ empty identifiers should not be allowed
// optimizely.SendOdpEvent("any", "any", null, null);
// optimizely.SendOdpEvent("any", "any", new Dictionary<string, string>(), null);
//
// // test missing/ empty action should not be allowed
// optimizely.SendOdpEvent("", "any", identifiers, null);
// optimizely.SendOdpEvent(null, "any", identifiers, null);
}

static void Main(string[] args)
{
/** ============================================
# CONFIG TYPE 1:
# default config, minimal settings
============================================
"""
TEST THE FOLLOWING:
- test creating user context with regular attributes
- test creating user context with prebuilt segments (no odp list), should get segments back, experiment should evaluate to true, decide response should look correct
- truth table - TBD
- 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
- may not need truth table test here (check)
- add RESET_CACHE and/or IGNORE_CACHE to fetch qualified segments call and repeat
- test send event
- verify events on ODP event inspector
- in send_event function uncomment lines of code that test missing identifiers and action keys, verify appropriate error is produced
- test audience segments (see spreadsheet
- test implicit/explicit ODP events?
- test integrations (no ODP integration added to project, integration is on, is off)
"""
**/
var optimizely = OptimizelyFactory.NewDefaultInstance("TbrfRLeKvLyWGusqANoeR");

var optimizelyConfig = optimizely.GetOptimizelyConfig();

var attributes = new UserAttributes();
attributes.Add("laptop_os", "mac");

var user = optimizely.CreateUserContext("fs-id-6", attributes);

FetchAndDecide(user);
SendEvent(optimizely);

optimizely.Dispose();

/** ============================================
# CONFIG TYPE 2:
# with ODP integration changed at app.optimizely.com - changed public key or host url
# VALID API key/HOST url- should work, INVALID KEY/URL-should get errors
# ============================================
"""
TEST THE FOLLOWING:
- test the same as in "CONFIG TYPE 1" but use invalid API key or HOST url
- TODO clarify with Jae what to test here !!!
""" **/
/*optimizely = OptimizelyFactory.NewDefaultInstance("TbrfRLeKvLyWGusqANoeR");

attributes = new UserAttributes();
attributes.Add("laptop_os", "mac");

// CASE 1 - REGULAR ATTRIBUTES, NO ODP
user = optimizely.CreateUserContext("user123", attributes);

// CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matehces DOB)
// user = optimizely.CreateUserContext("fs-id-12", attributes);

// CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6
// user = optimizely.CreateUserContext("fs-id-6", attributes);

FetchAndDecide(user);
SendEvent(optimizely);

optimizely.Dispose();*/

/** ============================================
# CONFIG TYPE 3:
# with different ODP configuration options (odpdisabled, segments_cache_size etc)
# ============================================
"""
TEST THE FOLLOWING:
same as in "CONFIG TYPE 1", but add config options to fetch qualified segments function, for example:
odp_disabled
segments_cache_size
segments_cache_timeout_in_secs
odp_segments_cache
odp_segment_manager
odp_event_manager
odp_segment_request_timeout
odp_event_request_timeout
odp_flush_interval

Observe responses and verity the correct behavior.
"""
**/
var logger = new DefaultLogger();
var errorHandler = new DefaultErrorHandler(logger, false);
var notificationCenter = new NotificationCenter();
var builder = new HttpProjectConfigManager.Builder();
var configManager = builder.WithSdkKey("TbrfRLeKvLyWGusqANoeR").
WithLogger(logger).
WithErrorHandler(errorHandler).
WithNotificationCenter(notificationCenter).
Build(false);
var handler = HttpProjectConfigManager.HttpClient.GetHttpClientHandler();
handler.UseProxy = false;

var fetchSegmentHttpClient = new HttpClient(handler);
fetchSegmentHttpClient.Timeout = TimeSpan.FromMilliseconds(10000);
var sendEventHttpClient = new HttpClient(handler);
sendEventHttpClient.Timeout = TimeSpan.FromMilliseconds(10000);

var odpEventApiManager = new OdpEventApiManager(logger, errorHandler, sendEventHttpClient);
var odpSegmentApiManager = new OdpSegmentApiManager(logger, errorHandler, fetchSegmentHttpClient);

var eventManagerBuilder = new OdpEventManager.Builder()
.WithOdpEventApiManager(odpEventApiManager)
.WithFlushInterval(TimeSpan.FromMilliseconds(1));

OdpSegmentManager odpSegmentManager = new OdpSegmentManager(odpSegmentApiManager, cacheSize: 1, itemTimeout: TimeSpan.FromSeconds(10), logger: logger);

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.
OdpManager odpManager = null;
if (!disableODP)
{
odpManager = new OdpManager.Builder()
.WithEventManager(eventManagerBuilder.Build())
.WithSegmentManager(odpSegmentManager)
.WithErrorHandler(errorHandler)
.WithLogger(logger)
.Build();
}
optimizely = new Optimizely(configManager, notificationCenter, null, logger, errorHandler, null, null, null, odpManager);

attributes = new UserAttributes();
attributes.Add("laptop_os", "mac");

// CASE 1 - REGULAR ATTRIBUTES, NO ODP
user = optimizely.CreateUserContext("user123", attributes);

// CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matches DOB)
// user = optimizely.CreateUserContext("fs-id-12", attributes);

// CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6
// user = optimizely.CreateUserContext("fs-id-6", attributes);

FetchAndDecide(user);
SendEvent(optimizely);

optimizely.Dispose();

Console.ReadLine();
}


}
}
36 changes: 36 additions & 0 deletions DemoConsoleApp/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DemoConsoleApp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DemoConsoleApp")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a0edce22-eecc-4407-839e-4743a1af8f51")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
5 changes: 5 additions & 0 deletions DemoConsoleApp/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="murmurhash-signed" version="1.0.2" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
</packages>
4 changes: 3 additions & 1 deletion OptimizelySDK.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.Net35", "Opti
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.Net40", "OptimizelySDK.Net40\OptimizelySDK.Net40.csproj", "{41AFD990-BC81-49E3-BD85-40972BB2C262}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.NetStandard20", "OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj", "{CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OptimizelySDK.NetStandard20", "OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj", "{CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoConsoleApp", "DemoConsoleApp\DemoConsoleApp.csproj", "{A0EDCE22-EECC-4407-839E-4743A1AF8F51}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
0