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");
}
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()));
}
}
}
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);
}
}
}
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);
}
}
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;
}
Aggregations