This repository has been archived by the owner on Jun 4, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Common Enrich: write out event vendor/name/format/version (closes sno…
- Loading branch information
Showing
5 changed files
with
183 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
...ain/scala/com.snowplowanalytics.snowplow.enrich/common/enrichments/SchemaEnrichment.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) 2012-2014 Snowplow Analytics Ltd. All rights reserved. | ||
* | ||
* This program is licensed to you under the Apache License Version 2.0, | ||
* and you may not use this file except in compliance with the Apache License Version 2.0. | ||
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the Apache License Version 2.0 is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. | ||
*/ | ||
package com.snowplowanalytics | ||
package snowplow | ||
package enrich | ||
package common | ||
package enrichments | ||
|
||
// Iglu | ||
import iglu.client.SchemaKey | ||
import iglu.client.Resolver | ||
|
||
// Jackson | ||
import com.fasterxml.jackson.databind.JsonNode | ||
import com.fasterxml.jackson.databind.node.TextNode | ||
|
||
// Common | ||
import outputs.EnrichedEvent | ||
import utils.shredder.Shredder | ||
|
||
// Scalaz | ||
import scalaz._ | ||
import Scalaz._ | ||
|
||
object SchemaEnrichment { | ||
|
||
val pageViewSchema = SchemaKey("com.snowplowanalytics.snowplow", "page_view", "jsonschema", "1-0-0").success | ||
val transactionSchema = SchemaKey("com.snowplowanalytics.snowplow", "transaction", "jsonschema", "1-0-0").success | ||
val transactionItemSchema = SchemaKey("com.snowplowanalytics.snowplow", "transaction_item", "jsonschema", "1-0-0").success | ||
val structSchema = SchemaKey("com.google.analytics", "event", "jsonschema", "1-0-0").success | ||
|
||
def extractSchema(event: EnrichedEvent)(implicit resolver: Resolver): Validation[String, SchemaKey] = event.event match { | ||
case "page_view" => pageViewSchema | ||
case "struct" => structSchema | ||
case "transaction" => transactionSchema | ||
case "transaction_item" => transactionItemSchema | ||
case "unstruct" => extractUnstructSchema(event) | ||
case eventType => "Unrecognized event [%s]".format(eventType).fail | ||
} | ||
|
||
private def extractUnstructSchema(event: EnrichedEvent)(implicit resolver: Resolver): Validation[String, SchemaKey] = { | ||
Shredder.extractUnstructEvent(event) match { | ||
case Some(Success(List(json))) => | ||
parseSchemaKey(Option(json.get("schema"))) | ||
case _ => | ||
"Unstructured event couldn't be extracted".fail | ||
} | ||
} | ||
|
||
private def parseSchemaKey(node: Option[JsonNode]): Validation[String, SchemaKey] = node match { | ||
case Some(textNode: TextNode) => | ||
SchemaKey.parse(textNode.textValue()).<-:(_.toString) | ||
case _ => | ||
"Unrecognized unstructured event structure".fail // It's validated by the Shredder, so it should never happen | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
...scala/com.snowplowanalytics.snowplow.enrich.common/enrichments/SchemaEnrichmentTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright (c) 2012-2014 Snowplow Analytics Ltd. All rights reserved. | ||
* | ||
* This program is licensed to you under the Apache License Version 2.0, | ||
* and you may not use this file except in compliance with the Apache License Version 2.0. | ||
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the Apache License Version 2.0 is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. | ||
*/ | ||
package com.snowplowanalytics.snowplow.enrich | ||
package common | ||
package enrichments | ||
|
||
// Iglu | ||
import com.snowplowanalytics.iglu.client.SchemaKey | ||
|
||
// Common | ||
import outputs.EnrichedEvent | ||
import enrichments.SchemaEnrichment._ | ||
|
||
// Specs2 | ||
import org.specs2.Specification | ||
import org.specs2.matcher.DataTables | ||
import org.specs2.scalaz.ValidationMatchers | ||
|
||
// Scalaz | ||
import scalaz._ | ||
import Scalaz._ | ||
|
||
class SchemaEnrichmentTest extends Specification with DataTables with ValidationMatchers { | ||
|
||
implicit val resolver = SpecHelpers.IgluResolver | ||
val signupFormSubmitted = """{"schema":"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0","data":{"schema":"iglu:com.snowplowanalytics.snowplow-website/signup_form_submitted/jsonschema/1-0-0","data":{"name":"Χαριτίνη NEW Unicode test","email":"alex+test@snowplowanalytics.com","company":"SP","eventsPerMonth":"< 1 million","serviceType":"unsure"}}}""" | ||
val signupFormSubmittedSchema = SchemaKey("com.snowplowanalytics.snowplow-website", "signup_form_submitted", "jsonschema", "1-0-0").success | ||
val invalidPayload = """{"schema":"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0","data":{"schema":"iglu:com.snowplowanalytics.snowplow-website/signup_form_submitted/jsonschema/1-0-0","data":{"serviceType":"unsure"}}}""" | ||
|
||
def is = | ||
"Extracting SchemaKeys from valid events should work" ! e1^ | ||
"Invalid events should fail when extracting SchemaKeys" ! e2 | ||
|
||
def e1 = | ||
"SPEC NAME" || "EVENT" | "EXPECTED SCHEMA" | | ||
"page view" !! event("page_view") ! pageViewSchema | | ||
"transaction" !! event("transaction") ! transactionSchema | | ||
"transaction item" !! event("transaction_item") ! transactionItemSchema | | ||
"struct event" !! event("struct") ! structSchema | | ||
"invalid unstruct event" !! unstructEvent(invalidPayload) ! signupFormSubmittedSchema | | ||
"unstruct event" !! unstructEvent(signupFormSubmitted) ! signupFormSubmittedSchema |> { | ||
(_, event, expected) => { | ||
val schema = SchemaEnrichment.extractSchema(event) | ||
schema must_== expected | ||
} | ||
} | ||
|
||
val nonSchemedPayload = """{"name":"Χαριτίνη NEW Unicode test","email":"alex+test@snowplowanalytics.com","company":"SP","eventsPerMonth":"< 1 million","serviceType":"unsure"}""" | ||
val invalidKeyPayload = """{"schema":"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0","data":{"schema":"iglu:com.snowplowanalytics.snowplow-website/signup_form_submitted/jsonschema","data":{"name":"Χαριτίνη NEW Unicode test","email":"alex+test@snowplowanalytics.com","company":"SP","eventsPerMonth":"< 1 million","serviceType":"unsure"}}}""" | ||
|
||
def e2 = | ||
"SPEC NAME" || "EVENT" | | ||
"unknown event" !! event("unknown") | | ||
"missing event" !! event(null) | | ||
"not schemed" !! unstructEvent(nonSchemedPayload) | | ||
"invalid key" !! unstructEvent(invalidKeyPayload) |> { | ||
(_, event) => { | ||
val schema = SchemaEnrichment.extractSchema(event) | ||
schema must beFailing | ||
} | ||
} | ||
|
||
def event(eventType: String) = { | ||
val event: EnrichedEvent = new EnrichedEvent() | ||
event.setEvent(eventType) | ||
event | ||
} | ||
|
||
def unstructEvent(unstruct: String) = { | ||
val event: EnrichedEvent = new EnrichedEvent() | ||
event.setEvent("unstruct") | ||
event.setUnstruct_event(unstruct) | ||
event | ||
} | ||
} |