Content
What are the CompetitionLabs Transformers / Common use cases for CompetitionLabs Transformers / Transform incoming messages from a Kafka or RabbitMQ Queue / Transform outgoing WebHook messages from CompetitionLabs / Example WebHook transformer / Developing and Testing Transformers / System Requirements / CompetitionLabs Transformer API
What are the CompetitionLabs Transformers
CompetitionLabs Transformers are a recommended way to integrate with the CompetitionLabs platform without having to make modifications to your message formats on your back-end systems. Using the CompetitionLabs Transformers, you can send a message to CompetitionLabs in your current format, transform the message into a form that can be accepted by the CompetitionLabs API, and push that message to CompetitionLabs. You can also transform messages before they are POSTed to your system via the CompetitionLabs WebHooks.
CompetitionLabs Transformers are created by writing small Scala classes that extend the CompetitionLabs Transformer classes to process messages.
Inbound events sent via RabbitMQ are transformed by extending the CLMQTransformer
class. Your transformation class is run by the CompetitionLabs platform when the message is received.
Outbound events sent via WebHooks are transformed by extending the CLWebhookTransformer
class. Your transformation class is run by the CompetitionLabs platform when an action occurs that would trigger a WebHook to fire.
If you want to | Write a class that extends |
Map your existing MQ messages to a CompetitionLabs Event | CLMQTransformer |
Map a CompetitionLabs WebHook message to a format your back-end systems accept | CLWebhookTransformer |
Common use cases for CompetitionLabs Transformers
Beyond mapping of message fields from your platform to CompetitionLabs, below are some common uses for CompetitionLabs Transformers:
- Create a new member when CompetitionLabs receives an event from a sign-up event
- Push a message into your platform when a new Product is created within CompetitionLabs
- Retrieve customer segment information from your platform for a new member
List of operations available can be found inside the github project.
Transform incoming messages from a RabbitMQ Queue
CompetitionLabs MQ transformer is used to transform a message received via RabbitMQ to your CompetitionLabs space. Within the transformer, you can map the fields of an incoming message to the CompetitionLabs API, trigger addition events, or implement custom business logic.
To transform an incoming message from a RabbitMQ Queue:
1. Create a class that extends the CLMQTransformer
class – Default Transformer
/*** * Copyright (C) Competition Labs Ltd - All Rights Reserved * Unauthorized copying of this file, via any medium is strictly prohibited * Proprietary and confidential * Written by Competition Labs Ltd, 2017 */ // Do not add additional imports from non-standard libraries import com.competitionlabs.transformers._ import com.competitionlabs.transformers.domain.BasicEventModel import org.joda.time.DateTime class CompetitionLabsMQTransformer extends CLMQTransformer { override def apply(message: Array[Byte], competitionLabsApi: CompetitionLabsApi) = { //////////////////////////////////////////////////// // 1. Extract the main data from our json body //////////////////////////////////////////////////// val messageAsString = competitionLabsApi.convertByteArrayToString(message) val messageAsJson = competitionLabsApi.fromJsonString(messageAsString) val jsonObj = messageAsJson val memberRef = Json.getFromJValue[String](jsonObj, "memberRefId") val batch = Json.getFromJValue[String](jsonObj, "batchId") val entityRef = Json.getFromJValue[String](jsonObj, "entityRefId") val eventRef = Json.getFromJValue[String](jsonObj, "eventRefId") val action = Json.getFromJValue[String](jsonObj, "action") val sourceValue = Json.getFromJValue[Double](jsonObj, "sourceValue") val transactionTimestamp = new DateTime(Json.getFromJValue[String](jsonObj, "transactionTimestamp")) //////////////////////////////////////////////////// // 2. Create data points if they are missing //////////////////////////////////////////////////// competitionLabsApi.memberIdFromMemberRefId(memberRef).getOrElse{ // Create a new member -> competitionLabsApi.createMember(memberRef, "unknown", Seq("new")) } competitionLabsApi.productIdFromProductRefId(entityRef).getOrElse{ // Create a new product competitionLabsApi.createProduct(entityRef, "unknown", Seq.empty, "slot", 0) } if(!competitionLabsApi.eventActionExists(action)) { // Create the action competitionLabsApi.createEventAction(action) } //////////////////////////////////////////////////// // 3. Lets decorate the event with our custom fields //////////////////////////////////////////////////// val customJson = jsonObj.\("metadata") val myCustomField1 = Json.getFromJValue[Int](customJson, "myCustomField1") val myCustomField2 = Json.getFromJValue[Int](customJson, "myCustomField2") val myCustomField3 = Json.getFromJValue[String](customJson, "myCustomField3") val customFields = new scala.collection.mutable.HashMap[String, Seq[Any]]() customFields.put("myCustomField1",Seq(myCustomField1)) customFields.put("myCustomField2",Seq(myCustomField2)) customFields.put("myCustomField3",Seq(myCustomField3)) //////////////////////////////////////////////////// // 4. Push the data to your CompetitionLabs space //////////////////////////////////////////////////// val event = BasicEventModel( action = action, tags = Seq.empty, eventRefId = eventRef, memberRefId = memberRef, entityRefId = entityRef, batchId = Option(batch), sourceValue = sourceValue, metadata = customFields.toMap, transactionTimestamp = transactionTimestamp ) competitionLabsApi.pushEvent(event) } }
2. Test your class using Scala Test and theCompetitionLabsApiTest
module – Transformer Test
/*** * Copyright (C) Competition Labs Ltd - All Rights Reserved * Unauthorized copying of this file, via any medium is strictly prohibited * Proprietary and confidential * Written by Competition Labs Ltd, 2017 */ package cl.test import cl.transformers import org.scalatest._ import utils.CompetitionLabsApiTest class CLRabbitMQTest extends FunSpec with Matchers with GivenWhenThen with BeforeAndAfterEach with BeforeAndAfterAll { describe("Test the CompetitionLabs message queue receiver implementation") { // Run the test it("should receive a published a message and transform it into a CompetitionLabs event") { // Prepare the test val transformer = new transformers.CompetitionLabsMQTransformer() val json = CLRabbitMQTest.jsonStringFromMq.toCharArray.map(_.toByte) val api = new CompetitionLabsApiTest() api.createMember("my-custom-member-ref-1","my-custom-member-ref-1", Seq("vip")) api.createEventAction("wager") api.createProduct("fruits","Fruits", Seq("CL"),"slot", 1) When("the message is forwarded") transformer.apply(json, api) Then("the event should be received") assert(api.eventsReceivedForTest.keySet.contains("fruits")) } } } object CLRabbitMQTest { val jsonStringFromMq: String = """{ "memberRefId": "my-custom-member-ref-1", "batchId": "some-batch-123456", "entityRefId": "fruits", "eventRefId": "your-system-event-id-1", "action": "wager", "sourceValue": 25, "transactionTimestamp": "2017-09-05T22:01:09.909+07:00", "metadata": { "myCustomField1": 1, "myCustomField2": 2.2, "myCustomField3": "one" } } """ }
Transform outgoing WebHook messages from CompetitionLabs
You can use CompetitionLabs WebHook transformers to modify and send messages to your WebHook endpoints. You can map field in the CompetitionLabs data model to fields already implemented in your platform. You can also use the CompetitionLabs Webhook Transformer API to trigger additional actions and events.
You can create a CompetitionLabs WebHook transformer for any of the built in WebHook events. If you have a customer WebHook transformer configured, your custom transformer is used instead of the built in WebHook transformer.
To create a CompetitionLabs WebHook transformer:
1. Create a new class that extends CLWebhookTransformer – Webhook Example
package example.transformers import com.competitionlabs.transformers.{CLWebhookTransformer, CompetitionLabsApiExt} import com.competitionlabs.transformers.domain.WebhookSettings class exampleWebHookTransformer extends CLWebhookTransformer { /** * Executed when a new member is registered in your CompetitionLabs space * @param settings The user supplied settings * @param memberId The CompetitionLabs member id * @param competitionLabsApi The CompetitionLabs API */ override def onNewMember(settings: WebhookSettings, memberId: String, competitionLabsApi: CompetitionLabsApiExt): Unit = { // Your transformation logic } }
2. Override one of the methods in CLWebhookTransformer with your implementation
The following are the built in WebHook transformers you can override with your own customer transformer:
- onAchievementCreated(): Executed when a new achievement is created
- onAchievementTriggered(): Executed when an achievement is triggered
- onAchievementRewardCreated(): Executed when a reward was created
- onAchievementRewardIssued(): Executed when a reward was awarded to a member
- onAchievementRewardClaimed(): Executed when a reward was claimed by a member
- onCompetitionCreated(): Executed when a new competition is created in your CompetitionLabs space
- onCompetitionStarted(): Executed when a competition is started
- onCompetitionFinished(): Executed when a competition finished
- onCompetitionCancelled(): Executed when a competition is cancelled
- onCompetitionRewardIssued(): Executed when a reward for a competition is issued
- onContestCreated(): Executed when a new contest is created in your CompetitionLabs space
- onContestStarted(): Executed when a contest is started
- onContestFinished(): Executed when a contest finished
- onContestFinalised(): Executed when a contest is finalised
- onContestCancelled(): Executed when a contest is cancelled
- onContestRewardIssued(): Executed when a contest reward is issued
- onContestRewardCreated(): Executed when a contest reward is created
- onContestRewardClaimed(): Executed when a contest reward is claimed
- onNewMember(): Executed when a new member is registered in your CompetitionLabs space
- onNewProduct(): Executed when a new product is registered in your CompetitionLabs space
Example of a WebHook transformer
Below is an example of a custom WebHook transformer.
import com.competitionlabs.transformers.domain.WebhookSettings import com.competitionlabs.transformers.{CLWebhookTransformer, CompetitionLabsApiExt} import org.joda.time.DateTime class DefaultWebhookTransformer extends CLWebhookTransformer { override def onAchievementTriggered(settings: WebhookSettings, achievementId: String, memberId: String, competitionLabsApi: CompetitionLabsApiExt): Unit = { val body = Map[String, Any]( "accountId" -> competitionLabsApi.accountId, "achievementId" -> achievementId, "memberId" -> memberId, "memberIdRefId" -> competitionLabsApi.memberRefIdFromMemberId(memberId), "resourcePath" -> s"/api/${competitionLabsApi.spaceName}/achievement/$achievementId", "timestamp" -> DateTime.now().getMillis ) val json = competitionLabsApi.toJsonFromMap(body) val headers = settings.headers ++ competitionLabsApi.HTTPDefaultHeader competitionLabsApi.httpPost(settings.url, json, headers) } }
Developing and Testing Transformers
This section covers the tools needed to begin writing and testing CompetitionLabs Transformers
System Requirements
These are the tools you will need to develop CompetitionLabs Transformers
- Scala 2.11
- Java 1.8
- JDK
- JetBrains
- IntelliJ (Optional)
CompetitionLabs Transformer API
The CompetitionLabs Transformer API is used within your transformer classes to perform various operations like looking up members, pushing events, creating actions, etc.
You can view the methods available for CLMQTransformer and CLWebhookTransformer classes here: competitionlabs-transformers/src/main/scala/com/competitionlabs/transformers/CompetitionLabsApi.scala
You can view addition methods available for CLWebhookTransformer classes here: clabs/competitionlabs-transformers/src/main/scala/com/competitionlabs/transformers/CompetitionLabsApiExt.scala
Github project is available at – competitionlabs-transformers
Once you have got your code working, get in touch with the CompetitionLabs admin team, they will provide you with a private repository to commit and deploy your custom transformers.