-
Notifications
You must be signed in to change notification settings - Fork 12
Moonshots XXI allow for use in declarative sfdc #20
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
public class EventSink implements EventSinkInterface { | ||
Integer maxEvents; | ||
private Integer eventsAddedCount; | ||
private Integer existingEventsCount; | ||
|
||
public EventSink(Integer maxEvents) { | ||
System.assertNotEquals(maxEvents, null); | ||
|
||
this.maxEvents = maxEvents; | ||
this.eventsAddedCount = 0; | ||
} | ||
|
||
public void sinkIdentify(LDEvent.Identify event) { | ||
|
@@ -24,9 +27,12 @@ public class EventSink implements EventSinkInterface { | |
} | ||
|
||
public void sinkGeneric(String kind, String raw) { | ||
Integer count = [SELECT COUNT() FROM EventData__c]; | ||
|
||
if (count >= this.maxEvents) { | ||
// Preserve SOQL queries (each transaction only gets 100) by getting count once and comparing to updated events count | ||
if (existingEventsCount == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: These instances all shared |
||
existingEventsCount = [SELECT COUNT() FROM EventData__c]; | ||
} | ||
// Only create event if threshold has not been met | ||
if ((existingEventsCount + eventsAddedCount) >= this.maxEvents) { | ||
return; | ||
} | ||
|
||
|
@@ -35,5 +41,6 @@ public class EventSink implements EventSinkInterface { | |
record.Raw__c = raw; | ||
|
||
insert record; | ||
eventsAddedCount++; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,134 @@ | ||||||
public class LDClientInvocable { | ||||||
|
||||||
public class InvocableRequest { | ||||||
@InvocableVariable(label='Flag Key' description='Flag Key as defined in LaunchDarkly' required=true) | ||||||
public String flagKey; | ||||||
@InvocableVariable(label='Flag Type' description='Flag Type corresponding to Flag Key. Valid options are: Boolean, Double, Integer, and String.' required=true) | ||||||
public String flagType; | ||||||
@InvocableVariable(label='Fallback (Boolean)' description='Fallback for Boolean Flag type if no variation found from LaunchDarkly' required=false) | ||||||
public Boolean booleanFallback; | ||||||
@InvocableVariable(label='Fallback (Double)' description='Fallback for Double (Number) Flag type if no variation found from LaunchDarkly' required=false) | ||||||
public Double doubleFallback; | ||||||
@InvocableVariable(label='Fallback (Integer)' description='Fallback for Integer (Number) Flag type if no variation found from LaunchDarkly' required=false) | ||||||
public Integer integerFallback; | ||||||
@InvocableVariable(label='Fallback (String)' description='Fallback for String Flag type if no variation found from LaunchDarkly' required=false) | ||||||
public String stringFallback; | ||||||
@InvocableVariable(label='LaunchDarkly Client' description='If provided, the LD Client can be persisted across requests to preserve SOQL queries and DML statements' required=false) | ||||||
public LDFlowClient ldClient_Flow; | ||||||
@InvocableVariable(label='User custom attributes' description='Key/Value pairs to assign to user context evaluation. Id and Name will be assigned automatically' required=false) | ||||||
public List<LDFlowMapKey> userCustomAttributes; | ||||||
@InvocableVariable(label='User to be Identified' description='If TRUE, the LDClient.identify method will be called' required=false) | ||||||
public Boolean userToBeIdentified; | ||||||
} | ||||||
|
||||||
public class InvocableResponse { | ||||||
@InvocableVariable(label='LaunchDarkly Client' description='Instance of LDClient used to retrieve the variation' required=false) | ||||||
public LDFlowClient ldClient_Flow; | ||||||
@InvocableVariable(label='Variation (Boolean)' description='Variation for Boolean Flag type' required=false) | ||||||
public Boolean booleanVariation; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this actually be null? |
||||||
@InvocableVariable(label='Variation (Double)' description='Variation for Double (Number) Flag type' required=false) | ||||||
public Double doubleVariation; | ||||||
@InvocableVariable(label='Variation (Integer)' description='Variation for Integer (Number) Flag type' required=false) | ||||||
public Integer integerVariation; | ||||||
@InvocableVariable(label='Variation (String)' description='Variation for String Flag type' required=false) | ||||||
public String stringVariation; | ||||||
|
||||||
public InvocableResponse(InvocableRequest request) { | ||||||
this.booleanVariation = false; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. q: why is this being set? |
||||||
} | ||||||
} | ||||||
|
||||||
@InvocableMethod(label='Get LaunchDarkly Variation' description='Returns the flag variation for a given of Flag Key') | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
public static List<InvocableResponse> flagVariation(List<InvocableRequest> requests) { | ||||||
LDClient client = determineClient(requests); | ||||||
LDFlowClient flowClient = new LDFlowClient(); | ||||||
flowClient.client = client; | ||||||
List<InvocableResponse> results = new List<InvocableResponse>(); | ||||||
for (InvocableRequest request : requests) { | ||||||
LDUser user = buildLDUser(client, request); | ||||||
InvocableResponse result = new InvocableResponse(request); | ||||||
result.ldClient_Flow = flowClient; | ||||||
if (request.flagType != null) { | ||||||
switch on request.flagType.toLowerCase() { | ||||||
when 'boolean' { | ||||||
result.booleanVariation = client.boolVariation(user, request.flagKey, request.booleanFallback != null ? request.booleanFallback : false); | ||||||
} | ||||||
when 'double' { | ||||||
result.doubleVariation = client.doubleVariation(user, request.flagKey, request.doubleFallback); | ||||||
} | ||||||
when 'integer' { | ||||||
result.integerVariation = client.intVariation(user, request.flagKey, request.integerFallback); | ||||||
} | ||||||
when 'string' { | ||||||
result.stringVariation = client.stringVariation(user, request.flagKey, request.stringFallback); | ||||||
} | ||||||
when else { | ||||||
} | ||||||
} | ||||||
} | ||||||
results.add(result); | ||||||
} | ||||||
return results; | ||||||
} | ||||||
|
||||||
private static LDClient determineClient(List<InvocableRequest> requests) { | ||||||
LDClient client; | ||||||
for (InvocableRequest request : requests) { | ||||||
if (client != null) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we just return on line 81? |
||||||
break; | ||||||
} | ||||||
if (request.ldClient_Flow != null) { | ||||||
client = request.ldClient_Flow.client; | ||||||
} | ||||||
} | ||||||
if (client == null) { | ||||||
client = new LDClient(); | ||||||
} | ||||||
|
||||||
return client; | ||||||
} | ||||||
|
||||||
private static LDUser buildLDUser(LDClient client, InvocableRequest request) { | ||||||
Map<String, LDValue> valueObjectMap = new Map<String, LDValue>(); | ||||||
if (request.userCustomAttributes != null) { | ||||||
for (LDFlowMapKey userAttribute : request.userCustomAttributes) { | ||||||
if (userAttribute.valueType != null) { | ||||||
switch on userAttribute.valueType.toLowerCase() { | ||||||
when 'boolean' { | ||||||
if (userAttribute.booleanValue != null) { | ||||||
valueObjectMap.put(userAttribute.key, LDValue.of(userAttribute.booleanValue)); | ||||||
} | ||||||
} | ||||||
when 'double' { | ||||||
if (userAttribute.doubleValue != null) { | ||||||
valueObjectMap.put(userAttribute.key, LDValue.of(userAttribute.doubleValue)); | ||||||
} | ||||||
} | ||||||
when 'integer' { | ||||||
if (userAttribute.integerValue != null) { | ||||||
valueObjectMap.put(userAttribute.key, LDValue.of(userAttribute.integerValue)); | ||||||
} | ||||||
} | ||||||
when 'string' { | ||||||
if (userAttribute.stringValue != null) { | ||||||
valueObjectMap.put(userAttribute.key, LDValue.of(userAttribute.stringValue)); | ||||||
} | ||||||
} | ||||||
when else { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
LDUser user = new LDUser.Builder(System.UserInfo.getUserId()) | ||||||
.setName(System.UserInfo.getName()) | ||||||
.setCustom(LDValueObject.fromMap(valueObjectMap)) | ||||||
.build(); | ||||||
|
||||||
if (request.userToBeIdentified == true) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
client.identify(user); | ||||||
} | ||||||
|
||||||
return user; | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="OrderController"> | ||
<apiVersion>49.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Used as an Apex-Defined Variable to allow LDClient persistance across variation calls | ||
public class LDFlowClient { | ||
@AuraEnabled | ||
public LDClient client; | ||
// clientName only included so that LDFlowClient is visible as an Apex-Defined Variable in the Flow | ||
@AuraEnabled | ||
public String clientName; | ||
|
||
public LDFlowClient(){} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="OrderController"> | ||
<apiVersion>49.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Used as an Apex-Defined Variable to allow map-like entry for user custom attributes | ||
public class LDFlowMapKey { | ||
@AuraEnabled | ||
public string key; | ||
@AuraEnabled | ||
public string valueType; | ||
@AuraEnabled | ||
public Boolean booleanValue; | ||
@AuraEnabled | ||
public Double doubleValue; | ||
@AuraEnabled | ||
public Integer integerValue; | ||
@AuraEnabled | ||
public string stringValue; | ||
|
||
public LDFlowMapKey(){} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="OrderController"> | ||
<apiVersion>49.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
putAll should have a comment saying that it's just used for the side-effect of updating the underlying data tables, and it's not going to have any effect on the Data Store instances used by SDK clients