Search in sources :

Example 1 with SchemaId

use of com.linkedin.databus2.schemas.SchemaId in project databus by linkedin.

the class HttpRelay method main.

public static void main(String[] args) throws Exception {
    Cli cli = new Cli();
    cli.processCommandLineArgs(args);
    cli.parseRelayConfig();
    StaticConfig staticConfig = cli.getRelayConfigBuilder().build();
    HttpRelay relay = new HttpRelay(staticConfig, cli.getPhysicalSourceStaticConfigs());
    RequestProcessorRegistry processorRegistry = relay.getProcessorRegistry();
    //Changes to add schemaId to event; DDSDBUS-3421
    //The long term fix is to remove DatabusEventRandomProducer in favour of RelayEventGenerator
    //The medium term fix is to send SchemaRegistry to DatabusEventRandomProducer, but move RandomProducer to databus-relay-impl (from databus-core-impl)
    //Reason: SchemaHelper classes required to parse/generate schemaId from schemaRegistry requires databus-schemas-core which depends on databus-core-impl
    SchemaRegistryService sr = relay.getSchemaRegistryService();
    HashMap<Long, byte[]> schemaIds = new HashMap<Long, byte[]>(staticConfig.getSourceIds().size());
    for (IdNamePair pair : staticConfig.getSourceIds()) {
        LOG.info("Http Relay Schema Reg:" + pair.getName() + " id=" + pair.getId());
        String schemaStr = sr.fetchLatestSchemaBySourceName(pair.getName());
        if (schemaStr != null) {
            Schema s = Schema.parse(schemaStr);
            byte[] sid = SchemaHelper.getSchemaId(s.toString());
            LOG.info("Found schema! Adding schemaId for sourceName=" + pair.getName() + " id=" + pair.getId() + " schemaId=" + sid);
            schemaIds.put(pair.getId(), sid);
        } else {
            byte[] defaultSid = "abcde".getBytes(Charset.defaultCharset());
            LOG.info("Didn't find schema! Adding default schemaId for sourceName=" + pair.getName() + "id=" + pair.getId() + " schemaId=" + defaultSid);
            schemaIds.put(pair.getId(), defaultSid);
        }
    }
    DatabusEventProducer randomEventProducer = new DatabusEventRandomProducer(relay.getEventBuffer(), 10, 100, 1000, staticConfig.getSourceIds(), schemaIds);
    // specify stats collector for this producer
    ((DatabusEventRandomProducer) randomEventProducer).setStatsCollector(relay.getInboundEventStatisticsCollector());
    processorRegistry.register(EchoRequestProcessor.COMMAND_NAME, new EchoRequestProcessor(null));
    processorRegistry.register(SleepRequestProcessor.COMMAND_NAME, new SleepRequestProcessor(null));
    processorRegistry.register(GenerateDataEventsRequestProcessor.COMMAND_NAME, new GenerateDataEventsRequestProcessor(null, relay, randomEventProducer));
    processorRegistry.register(LoadDataEventsRequestProcessor.COMMAND_NAME, new LoadDataEventsRequestProcessor(relay.getDefaultExecutorService(), relay));
    LOG.info("source = " + relay.getSourcesIdNameRegistry().getAllSources());
    try {
        relay.registerShutdownHook();
        relay.startAndBlock();
    } catch (Exception e) {
        LOG.error("Error starting the relay", e);
    }
    LOG.info("Exiting relay");
}
Also used : DatabusEventRandomProducer(com.linkedin.databus.core.util.DatabusEventRandomProducer) EchoRequestProcessor(com.linkedin.databus2.core.container.request.EchoRequestProcessor) LoadDataEventsRequestProcessor(com.linkedin.databus.container.request.LoadDataEventsRequestProcessor) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) FileSystemSchemaRegistryService(com.linkedin.databus2.schemas.FileSystemSchemaRegistryService) SchemaRegistryService(com.linkedin.databus2.schemas.SchemaRegistryService) Schema(org.apache.avro.Schema) DataSourcesStaticConfig(com.linkedin.databus2.relay.config.DataSourcesStaticConfig) SchemaRegistryStaticConfig(com.linkedin.databus2.schemas.SchemaRegistryStaticConfig) PhysicalSourceStaticConfig(com.linkedin.databus2.relay.config.PhysicalSourceStaticConfig) SleepRequestProcessor(com.linkedin.databus2.core.container.request.SleepRequestProcessor) BufferNotFoundException(com.linkedin.databus2.core.BufferNotFoundException) DatabusException(com.linkedin.databus2.core.DatabusException) InvalidConfigException(com.linkedin.databus.core.util.InvalidConfigException) UnsupportedKeyException(com.linkedin.databus.core.UnsupportedKeyException) SQLException(java.sql.SQLException) JsonMappingException(org.codehaus.jackson.map.JsonMappingException) EventCreationException(com.linkedin.databus2.producers.EventCreationException) IOException(java.io.IOException) JsonParseException(org.codehaus.jackson.JsonParseException) RequestProcessorRegistry(com.linkedin.databus2.core.container.request.RequestProcessorRegistry) IdNamePair(com.linkedin.databus.core.util.IdNamePair) DatabusEventProducer(com.linkedin.databus.core.util.DatabusEventProducer) GenerateDataEventsRequestProcessor(com.linkedin.databus.container.request.GenerateDataEventsRequestProcessor)

Example 2 with SchemaId

use of com.linkedin.databus2.schemas.SchemaId in project databus by linkedin.

the class RegisterRequestProcessor method getMetadataSchemas.

/**
   * Returns list of versioned metadata schemas.
   * TODO (DDSDBUS-2093):  implement this.
   */
private // IN
void getMetadataSchemas(// IN
SchemaRegistryService schemaRegistry, // OUT
ArrayList<RegisterResponseMetadataEntry> registeredMetadata) throws RequestProcessingException {
    Map<SchemaId, VersionedSchema> versionedSchemas = null;
    try {
        VersionedSchemaSet schemaSet = schemaRegistry.fetchAllMetadataSchemaVersions();
        if (schemaSet != null) {
            versionedSchemas = schemaSet.getAllVersionsWithSchemaId(SchemaRegistryService.DEFAULT_METADATA_SCHEMA_SOURCE);
        }
    } catch (DatabusException ie) {
        HttpStatisticsCollector relayStatsCollector = _relay.getHttpStatisticsCollector();
        if (relayStatsCollector != null)
            relayStatsCollector.registerInvalidRegisterCall();
        throw new RequestProcessingException(ie);
    }
    if (versionedSchemas != null && !versionedSchemas.isEmpty()) {
        for (SchemaId id : versionedSchemas.keySet()) {
            VersionedSchema entry = versionedSchemas.get(id);
            if (entry.getOrigSchemaStr() == null) {
                throw new RequestProcessingException("Null schema string for metadata version " + entry.getVersion());
            }
            registeredMetadata.add(new RegisterResponseMetadataEntry((short) entry.getVersion(), entry.getOrigSchemaStr(), id.getByteArray()));
        }
    }
}
Also used : DatabusException(com.linkedin.databus2.core.DatabusException) RegisterResponseMetadataEntry(com.linkedin.databus2.core.container.request.RegisterResponseMetadataEntry) HttpStatisticsCollector(com.linkedin.databus2.core.container.monitoring.mbean.HttpStatisticsCollector) SchemaId(com.linkedin.databus2.schemas.SchemaId) RequestProcessingException(com.linkedin.databus2.core.container.request.RequestProcessingException) VersionedSchemaSet(com.linkedin.databus2.schemas.VersionedSchemaSet) VersionedSchema(com.linkedin.databus2.schemas.VersionedSchema)

Example 3 with SchemaId

use of com.linkedin.databus2.schemas.SchemaId in project databus by linkedin.

the class GoldenGateEventProducer method addEventToBuffer.

/**
   *
   * @param dbUpdates  The dbUpdates present in the current transaction
   * @param ti The meta information about the transaction. (See TransactionInfo class for more details).
   * @throws DatabusException
   * @throws UnsupportedKeyException
   */
protected void addEventToBuffer(List<TransactionState.PerSourceTransactionalUpdate> dbUpdates, TransactionInfo ti) throws DatabusException, UnsupportedKeyException {
    if (dbUpdates.size() == 0)
        throw new DatabusException("Cannot handle empty dbUpdates");
    long scn = ti.getScn();
    long timestamp = ti.getTransactionTimeStampNs();
    EventSourceStatistics globalStats = getSource(GLOBAL_SOURCE_ID).getStatisticsBean();
    /**
     * We skip the start scn of the relay, we have already added a EOP for this SCN in the buffer.
     * Why is this not a problem ?
     * There are two cases:
     * 1. When we use the earliest/latest scn if there is no maxScn (We don't really have a start point). So it's really OK to miss the first event.
     * 2. If it's the maxSCN, then event was already seen by the relay.
     */
    if (scn == _startPrevScn.get()) {
        _log.info("Skipping this transaction, EOP already send for this event");
        return;
    }
    getEventBuffer().startEvents();
    int eventsInTransactionCount = 0;
    List<EventReaderSummary> summaries = new ArrayList<EventReaderSummary>();
    for (int i = 0; i < dbUpdates.size(); ++i) {
        GenericRecord record = null;
        TransactionState.PerSourceTransactionalUpdate perSourceUpdate = dbUpdates.get(i);
        short sourceId = (short) perSourceUpdate.getSourceId();
        // prepare stats collection per source
        EventSourceStatistics perSourceStats = getSource(sourceId).getStatisticsBean();
        Iterator<DbUpdateState.DBUpdateImage> dbUpdateIterator = perSourceUpdate.getDbUpdatesSet().iterator();
        int eventsInDbUpdate = 0;
        long dbUpdatesEventsSize = 0;
        long startDbUpdatesMs = System.currentTimeMillis();
        while (//TODO verify if there is any case where we need to rollback.
        dbUpdateIterator.hasNext()) {
            DbUpdateState.DBUpdateImage dbUpdate = dbUpdateIterator.next();
            //Construct the Databus Event key, determine the key type and construct the key
            Object keyObj = obtainKey(dbUpdate);
            DbusEventKey eventKey = new DbusEventKey(keyObj);
            //Get the logicalparition id
            PartitionFunction partitionFunction = _partitionFunctionHashMap.get((int) sourceId);
            short lPartitionId = partitionFunction.getPartition(eventKey);
            record = dbUpdate.getGenericRecord();
            //Write the event to the buffer
            if (record == null)
                throw new DatabusException("Cannot write event to buffer because record = " + record);
            if (record.getSchema() == null)
                throw new DatabusException("The record does not have a schema (null schema)");
            try {
                //Collect stats on number of dbUpdates for one source
                eventsInDbUpdate++;
                //Count of all the events in the current transaction
                eventsInTransactionCount++;
                // Serialize the row
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                Encoder encoder = new BinaryEncoder(bos);
                GenericDatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(record.getSchema());
                writer.write(record, encoder);
                byte[] serializedValue = bos.toByteArray();
                //Get the md5 for the schema
                SchemaId schemaId = SchemaId.createWithMd5(dbUpdate.getSchema());
                //Determine the operation type and convert to dbus opcode
                DbusOpcode opCode;
                if (dbUpdate.getOpType() == DbUpdateState.DBUpdateImage.OpType.INSERT || dbUpdate.getOpType() == DbUpdateState.DBUpdateImage.OpType.UPDATE) {
                    opCode = DbusOpcode.UPSERT;
                    if (_log.isDebugEnabled())
                        _log.debug("The event with scn " + scn + " is INSERT/UPDATE");
                } else if (dbUpdate.getOpType() == DbUpdateState.DBUpdateImage.OpType.DELETE) {
                    opCode = DbusOpcode.DELETE;
                    if (_log.isDebugEnabled())
                        _log.debug("The event with scn " + scn + " is DELETE");
                } else {
                    throw new DatabusException("Unknown opcode from dbUpdate for event with scn:" + scn);
                }
                //Construct the dbusEvent info
                DbusEventInfo dbusEventInfo = new DbusEventInfo(opCode, scn, (short) _pConfig.getId(), lPartitionId, timestamp, sourceId, schemaId.getByteArray(), serializedValue, false, false);
                dbusEventInfo.setReplicated(dbUpdate.isReplicated());
                perSourceStats.addEventCycle(1, ti.getTransactionTimeRead(), serializedValue.length, scn);
                globalStats.addEventCycle(1, ti.getTransactionTimeRead(), serializedValue.length, scn);
                long tsEnd = System.currentTimeMillis();
                perSourceStats.addTimeOfLastDBAccess(tsEnd);
                globalStats.addTimeOfLastDBAccess(tsEnd);
                //Append to the event buffer
                getEventBuffer().appendEvent(eventKey, dbusEventInfo, _statsCollector);
                _rc.incrementEventCount();
                dbUpdatesEventsSize += serializedValue.length;
            } catch (IOException io) {
                perSourceStats.addError();
                globalStats.addEmptyEventCycle();
                _log.error("Cannot create byte stream payload: " + dbUpdates.get(i).getSourceId());
            }
        }
        long endDbUpdatesMs = System.currentTimeMillis();
        long dbUpdatesElapsedTimeMs = endDbUpdatesMs - startDbUpdatesMs;
        // Log Event Summary at logical source level
        EventReaderSummary summary = new EventReaderSummary(sourceId, _monitoredSources.get(sourceId).getSourceName(), scn, eventsInDbUpdate, dbUpdatesEventsSize, -1L, /* Not supported */
        dbUpdatesElapsedTimeMs, timestamp, timestamp, -1L);
        if (_eventsLog.isInfoEnabled()) {
            _eventsLog.info(summary.toString());
        }
        summaries.add(summary);
        if (_log.isDebugEnabled())
            _log.debug("There are " + eventsInDbUpdate + " events seen in the current dbUpdate");
    }
    // Log Event Summary at Physical source level
    ReadEventCycleSummary summary = new ReadEventCycleSummary(_pConfig.getName(), summaries, scn, -1);
    if (_eventsLog.isInfoEnabled()) {
        _eventsLog.info(summary.toString());
    }
    _log.info("Writing " + eventsInTransactionCount + " events from transaction with scn: " + scn);
    if (scn <= 0)
        throw new DatabusException("Unable to write events to buffer because of negative/zero scn: " + scn);
    getEventBuffer().endEvents(scn, _statsCollector);
    _scn.set(scn);
    if (getMaxScnReaderWriter() != null) {
        try {
            getMaxScnReaderWriter().saveMaxScn(_scn.get());
        } catch (DatabusException e) {
            _log.error("Cannot save scn = " + _scn + " for physical source = " + getName(), e);
        }
    }
}
Also used : PartitionFunction(com.linkedin.databus2.producers.PartitionFunction) TransactionState(com.linkedin.databus2.ggParser.XmlStateMachine.TransactionState) ArrayList(java.util.ArrayList) EventSourceStatistics(com.linkedin.databus.monitoring.mbean.EventSourceStatistics) DbusEventInfo(com.linkedin.databus.core.DbusEventInfo) ReadEventCycleSummary(com.linkedin.databus2.producers.db.ReadEventCycleSummary) EventReaderSummary(com.linkedin.databus2.producers.db.EventReaderSummary) Encoder(org.apache.avro.io.Encoder) BinaryEncoder(org.apache.avro.io.BinaryEncoder) DbusOpcode(com.linkedin.databus.core.DbusOpcode) GenericRecord(org.apache.avro.generic.GenericRecord) DbUpdateState(com.linkedin.databus2.ggParser.XmlStateMachine.DbUpdateState) ByteArrayOutputStream(java.io.ByteArrayOutputStream) GenericDatumWriter(org.apache.avro.generic.GenericDatumWriter) IOException(java.io.IOException) DatabusException(com.linkedin.databus2.core.DatabusException) BinaryEncoder(org.apache.avro.io.BinaryEncoder) SchemaId(com.linkedin.databus2.schemas.SchemaId) PerSourceTransactionalUpdate(com.linkedin.databus2.ggParser.XmlStateMachine.TransactionState.PerSourceTransactionalUpdate) DbusEventKey(com.linkedin.databus.core.DbusEventKey)

Example 4 with SchemaId

use of com.linkedin.databus2.schemas.SchemaId in project databus by linkedin.

the class TestDatabusRelayEvents method testEventConversion.

@Test
public /**
   * append event V2 to the buffer and stream it to the client
   * which only accepts events V1. Make sure it got converted
   */
void testEventConversion() throws InterruptedException, IOException, DatabusException {
    final Logger log = Logger.getLogger("TestDatabusRelayEvents.testEventConversion");
    log.setLevel(Level.INFO);
    DatabusRelayTestUtil.RelayRunner r1 = null;
    ClientRunner cr = null;
    try {
        String[] srcs = { "com.linkedin.events.example.fake.FakeSchema" };
        int pId = 1;
        int srcId = 2;
        int relayPort = Utils.getAvailablePort(11994);
        ;
        final DatabusRelayMain relay1 = createRelay(relayPort, pId, srcs);
        Assert.assertNotNull(relay1);
        r1 = new DatabusRelayTestUtil.RelayRunner(relay1);
        log.info("Relay created");
        DbusEventBufferMult bufMult = relay1.getEventBuffer();
        String pSourceName = DatabusRelayTestUtil.getPhysicalSrcName(srcs[0]);
        PhysicalPartition pPartition = new PhysicalPartition(pId, pSourceName);
        DbusEventBufferAppendable buf = bufMult.getDbusEventBufferAppendable(pPartition);
        DbusEventKey key = new DbusEventKey(123L);
        byte[] schemaId = relay1.getSchemaRegistryService().fetchSchemaIdForSourceNameAndVersion(srcs[0], 2).getByteArray();
        byte[] payload = RngUtils.randomString(100).getBytes(Charset.defaultCharset());
        DbusEventInfo eventInfo = new DbusEventInfo(DbusOpcode.UPSERT, 100L, (short) pId, (short) pId, 897L, (short) srcId, schemaId, payload, false, true);
        eventInfo.setEventSerializationVersion(DbusEventFactory.DBUS_EVENT_V2);
        buf.startEvents();
        buf.appendEvent(key, eventInfo, null);
        buf.endEvents(100L, null);
        r1.start();
        log.info("Relay started");
        // wait until relay comes up
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return relay1.isRunningStatus();
            }
        }, "Relay hasn't come up completely ", 7000, LOG);
        // now create client:
        String srcSubscriptionString = TestUtil.join(srcs, ",");
        String serverName = "localhost:" + relayPort;
        final EventsCountingConsumer countingConsumer = new EventsCountingConsumer();
        int id = (RngUtils.randomPositiveInt() % 10000) + 1;
        DatabusSourcesConnection clientConn = RelayEventProducer.createDatabusSourcesConnection("testProducer", id, serverName, srcSubscriptionString, countingConsumer, 1 * 1024 * 1024, 50000, 30 * 1000, 100, 15 * 1000, 1, true, DatabusClientNettyThreadPools.createNettyThreadPools(id), 0, DbusEventFactory.DBUS_EVENT_V1, 0);
        cr = new ClientRunner(clientConn);
        cr.start();
        log.info("Consumer started");
        // wait till client gets the event
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return countingConsumer.getNumDataEvents() == 1;
            }
        }, "Consumer didn't get any events ", 64 * 1024, LOG);
        // asserts
        Assert.assertEquals(1, countingConsumer.getNumDataEvents());
        Assert.assertEquals(1, countingConsumer.getNumWindows());
        Assert.assertEquals(1, countingConsumer.getNumDataEvents(DbusEventFactory.DBUS_EVENT_V1));
    } finally {
        cleanup(new DatabusRelayTestUtil.RelayRunner[] { r1 }, cr);
    }
}
Also used : ConditionCheck(com.linkedin.databus2.test.ConditionCheck) ClientRunner(com.linkedin.databus2.relay.TestDatabusRelayMain.ClientRunner) DbusEventBufferAppendable(com.linkedin.databus.core.DbusEventBufferAppendable) Logger(org.apache.log4j.Logger) DatabusSourcesConnection(com.linkedin.databus.client.DatabusSourcesConnection) DbusEventInfo(com.linkedin.databus.core.DbusEventInfo) DatabusRelayTestUtil(com.linkedin.databus2.relay.util.test.DatabusRelayTestUtil) DbusEventBufferMult(com.linkedin.databus.core.DbusEventBufferMult) DbusEventKey(com.linkedin.databus.core.DbusEventKey) PhysicalPartition(com.linkedin.databus.core.data_model.PhysicalPartition) Test(org.testng.annotations.Test)

Example 5 with SchemaId

use of com.linkedin.databus2.schemas.SchemaId in project databus by linkedin.

the class DbusEventAvroDecoder method getTypedValue.

@Override
public <T extends SpecificRecord> T getTypedValue(DbusEvent e, T reuse, Class<T> targetClass) {
    if (null == reuse) {
        try {
            reuse = targetClass.newInstance();
        } catch (InstantiationException e1) {
            LOG.error("getTypedValue class instantiation error (" + e1.getMessage() + ") for event " + e, e1);
            return null;
        } catch (IllegalAccessException e1) {
            LOG.error("getTypedValue access error (" + e1.getMessage() + ") for event " + e, e1);
            return null;
        }
    }
    byte[] md5 = new byte[16];
    e.schemaId(md5);
    SchemaId schemaId = new SchemaId(md5);
    VersionedSchema writerSchema = _schemaSet.getById(schemaId);
    if (null == writerSchema) {
        LOG.error("Unable to find schema for id " + schemaId + "; event = " + e);
        throw new DatabusRuntimeException("No schema available to decode event " + e);
    }
    ByteBuffer valueBuffer = e.value();
    byte[] valueBytes = new byte[valueBuffer.remaining()];
    valueBuffer.get(valueBytes);
    try {
        //JsonDecoder jsonDec = new JsonDecoder(sourceSchema.getSchema(),new ByteArrayInputStream(valueBytes));
        binDecoder.set(DecoderFactory.defaultFactory().createBinaryDecoder(valueBytes, binDecoder.get()));
        SpecificDatumReader<SpecificRecord> reader = new SpecificDatumReader<SpecificRecord>(writerSchema.getSchema(), reuse.getSchema());
        return targetClass.cast(reader.read(reuse, binDecoder.get()));
    } catch (IOException e1) {
        LOG.error("getTypedValue IO error (" + e1.getMessage() + ") for event " + e, e1);
    }
    return reuse;
}
Also used : SpecificRecord(org.apache.avro.specific.SpecificRecord) SchemaId(com.linkedin.databus2.schemas.SchemaId) IOException(java.io.IOException) SpecificDatumReader(org.apache.avro.specific.SpecificDatumReader) VersionedSchema(com.linkedin.databus2.schemas.VersionedSchema) ByteBuffer(java.nio.ByteBuffer) DatabusRuntimeException(com.linkedin.databus.core.DatabusRuntimeException)

Aggregations

SchemaId (com.linkedin.databus2.schemas.SchemaId)14 VersionedSchema (com.linkedin.databus2.schemas.VersionedSchema)6 VersionedSchemaSet (com.linkedin.databus2.schemas.VersionedSchemaSet)5 Test (org.testng.annotations.Test)5 IOException (java.io.IOException)4 ByteBuffer (java.nio.ByteBuffer)4 GenericRecord (org.apache.avro.generic.GenericRecord)4 DbusEventAvroDecoder (com.linkedin.databus.client.DbusEventAvroDecoder)3 DbusEvent (com.linkedin.databus.core.DbusEvent)3 DbusEventInfo (com.linkedin.databus.core.DbusEventInfo)3 DbusEventKey (com.linkedin.databus.core.DbusEventKey)3 DatabusException (com.linkedin.databus2.core.DatabusException)3 RegisterResponseMetadataEntry (com.linkedin.databus2.core.container.request.RegisterResponseMetadataEntry)3 HashMap (java.util.HashMap)3 DatabusRuntimeException (com.linkedin.databus.core.DatabusRuntimeException)2 DbusEventPart (com.linkedin.databus.core.DbusEventPart)2 IdNamePair (com.linkedin.databus.core.util.IdNamePair)2 RegisterResponseEntry (com.linkedin.databus2.core.container.request.RegisterResponseEntry)2 DatabusSourcesConnection (com.linkedin.databus.client.DatabusSourcesConnection)1 SCN (com.linkedin.databus.client.pub.SCN)1