Skip to content

Commit

Permalink
refactor: event-parser to report errors
Browse files Browse the repository at this point in the history
  • Loading branch information
aleortega committed Sep 25, 2024
1 parent b93bf72 commit e8f0dd8
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 104 deletions.
194 changes: 102 additions & 92 deletions src/adapters/event-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
VerticalHeightReachedEvent,
WalkedDistanceEvent
} from '@dcl/schemas'
import { AppComponents, IEventParser } from '../types'

enum ExplorerEventIds {
MOVE_TO_PARCEL = 'move_to_parcel',
Expand All @@ -16,108 +17,117 @@ enum ExplorerEventIds {
VERTICAL_HEIGHT_REACHED = 'vertical_height_reached'
}

function parseExplorerClientEvent(event: any): Event | undefined {
if (!event || !event.event) return undefined
export function createEventParserComponent({ logs }: Pick<AppComponents, 'logs'>): IEventParser {
const logger = logs.getLogger('event-parser')

if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.MOVE_TO_PARCEL) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.MOVE_TO_PARCEL,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
parcel: {
isEmptyParcel: event.properties.is_empty_parcel,
newParcel: event.properties.new_parcel,
oldParcel: event.properties.old_parcel,
sceneHash: event.properties.scene_hash
}
function parseExplorerClientEvent(event: any): Event | undefined {
try {
if (!event || !event.event) return undefined

if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.MOVE_TO_PARCEL) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.MOVE_TO_PARCEL,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
parcel: {
isEmptyParcel: event.properties.is_empty_parcel,
newParcel: event.properties.new_parcel,
oldParcel: event.properties.old_parcel,
sceneHash: event.properties.scene_hash
}
}
} as MoveToParcelEvent
}
} as MoveToParcelEvent
}

if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.USED_EMOTE) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.USED_EMOTE,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
emote: {
emoteIndex: event.properties.emote_index,
isBase: event.properties.is_base,
itemId: event.properties.item_id,
source: event.properties.source
}
if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.USED_EMOTE) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.USED_EMOTE,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
emote: {
emoteIndex: event.properties.emote_index,
isBase: event.properties.is_base,
itemId: event.properties.item_id,
source: event.properties.source
}
}
} as UsedEmoteEvent
}
} as UsedEmoteEvent
}

if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.PASSPORT_OPENED) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.PASSPORT_OPENED,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
passport: {
receiver: event.properties.receiver_id
}
if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.PASSPORT_OPENED) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.PASSPORT_OPENED,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
passport: {
receiver: event.properties.receiver_id
}
}
} as PassportOpenedEvent
}
} as PassportOpenedEvent
}

if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.WALKED_DISTANCE) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.WALKED_DISTANCE,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
distance: event.properties.distance,
stepCount: event.properties.step_count
if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.WALKED_DISTANCE) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.WALKED_DISTANCE,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
distance: event.properties.distance,
stepCount: event.properties.step_count
}
} as WalkedDistanceEvent
}
} as WalkedDistanceEvent
}

if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.VERTICAL_HEIGHT_REACHED) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.VERTICAL_HEIGHT_REACHED,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
height: event.properties.height
if ((event.event as string).toLocaleLowerCase() === ExplorerEventIds.VERTICAL_HEIGHT_REACHED) {
return {
type: Events.Type.CLIENT,
subType: Events.SubType.Client.VERTICAL_HEIGHT_REACHED,
timestamp: new Date(event.timestamp).getTime(),
key: event.messageId,
metadata: {
authChain: JSON.parse(event.context.auth_chain),
userAddress: event.context.dcl_eth_address,
sessionId: event.context.session_id,
timestamp: event.sentAt,
realm: event.context.realm,
height: event.properties.height
}
} as VerticalHeightReachedEvent
}
} as VerticalHeightReachedEvent

return undefined
} catch (error: any) {
logger.error(`Error parsing event: ${error.message}`, { event })
return undefined
}
}

return undefined
return { parseExplorerClientEvent }
}

export { parseExplorerClientEvent }
4 changes: 3 additions & 1 deletion src/adapters/event-publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { PublishCommand, SNSClient } from '@aws-sdk/client-sns'
import { AppComponents, IEventPublisher } from '../types'
import { Event } from '@dcl/schemas'

export async function createEventPublisher({ config }: Pick<AppComponents, 'config'>): Promise<IEventPublisher> {
export async function createEventPublisherComponent({
config
}: Pick<AppComponents, 'config'>): Promise<IEventPublisher> {
const snsArn = await config.requireString('AWS_SNS_ARN')
const optionalEndpoint = await config.getString('AWS_SNS_ENDPOINT')

Expand Down
8 changes: 6 additions & 2 deletions src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { bidAcceptedProducer } from './adapters/producers/bid-accepted'
import { rentalStartedProducer } from './adapters/producers/rental-started'
import { rentalEndedProducer } from './adapters/producers/rental-ended'
import { createProducer } from './adapters/create-producer'
import { createEventPublisher } from './adapters/event-publisher'
import { createEventPublisherComponent } from './adapters/event-publisher'
import { createDatabaseComponent } from './adapters/database'
import {
createServerComponent,
Expand All @@ -24,6 +24,7 @@ import {
} from '@well-known-components/http-server'
import { collectionCreatedProducer } from './adapters/producers/collection-created'
import { itemPublishedProducer } from './adapters/producers/item-published'
import { createEventParserComponent } from './adapters/event-parser'

// Initialize all the components of the app
export async function initComponents(): Promise<AppComponents> {
Expand Down Expand Up @@ -85,7 +86,7 @@ export async function initComponents(): Promise<AppComponents> {
const marketplaceSubGraphUrl = await config.requireString('MARKETPLACE_SUBGRAPH_URL')
const marketplaceSubGraph = await createSubgraphComponent({ config, logs, metrics, fetch }, marketplaceSubGraphUrl)

const eventPublisher = await createEventPublisher({ config })
const eventPublisher = await createEventPublisherComponent({ config })

// Create the producer registry and add all the producers
const producerRegistry = await createProducerRegistry({ logs })
Expand Down Expand Up @@ -132,6 +133,8 @@ export async function initComponents(): Promise<AppComponents> {
await createProducer({ logs, database, eventPublisher }, await collectionCreatedProducer({ l2CollectionsSubGraph }))
)

const eventParser = createEventParserComponent({ logs })

return {
config,
logs,
Expand All @@ -141,6 +144,7 @@ export async function initComponents(): Promise<AppComponents> {
database,
fetch,
eventPublisher,
eventParser,
l2CollectionsSubGraph,
landManagerSubGraph,
rentalsSubGraph,
Expand Down
25 changes: 16 additions & 9 deletions src/controllers/handlers/forward-explorer-events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { parseExplorerClientEvent } from '../../adapters/event-parser'
import { HandlerContextWithPath } from '../../types'
import crypto from 'crypto'

Expand All @@ -21,12 +20,13 @@ function validateIfSegmentIsTheSourceOfTheEvent(

export async function setForwardExplorerEventsHandler(
context: Pick<
HandlerContextWithPath<'eventPublisher' | 'config' | 'logs', '/forward'>,
HandlerContextWithPath<'eventPublisher' | 'eventParser' | 'config' | 'logs', '/forward'>,
'params' | 'request' | 'components'
>
) {
const logger = context.components.logs.getLogger('forward-explorer-events')
const segmentSignigKey = await context.components.config.requireString('SEGMENT_SIGNING_KEY')
const { logs, config, eventParser, eventPublisher } = context.components
const logger = logs.getLogger('forward-explorer-events')
const segmentSignigKey = await config.requireString('SEGMENT_SIGNING_KEY')

const body = await context.request.json()
const signatureHeader = context.request.headers.get('x-signature')
Expand All @@ -46,12 +46,19 @@ export async function setForwardExplorerEventsHandler(
}
}

const parsedEvent = parseExplorerClientEvent(body)
const parsedEvent = eventParser.parseExplorerClientEvent(body)

if (!parsedEvent) {
logger.warn('Invalid event', {
body: JSON.stringify(body)
})
if (typeof body === 'object' && body !== null) {
logger.warn('Invalid event', {
body: JSON.stringify(body)
})
} else {
logger.warn('Invalid event', {
body
})
}

return {
status: 400,
body: {
Expand All @@ -61,7 +68,7 @@ export async function setForwardExplorerEventsHandler(
}
}

await context.components.eventPublisher.publishMessage(parsedEvent)
await eventPublisher.publishMessage(parsedEvent)

logger.info('Event parsed and forwarded', {
parsedEvent: JSON.stringify(parsedEvent)
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type BaseComponents = {
fetch: IFetchComponent
producerRegistry: IProducerRegistry
eventPublisher: IEventPublisher
eventParser: IEventParser
}

// components used in runtime
Expand Down Expand Up @@ -88,3 +89,7 @@ export type IProducerRegistry = IBaseComponent & {
export type IEventPublisher = {
publishMessage(event: Event): Promise<string | undefined>
}

export type IEventParser = {
parseExplorerClientEvent(event: any): Event | undefined
}

0 comments on commit e8f0dd8

Please sign in to comment.