Search in sources :

Example 41 with StreamEvent

use of co.cask.cdap.api.flow.flowlet.StreamEvent in project cdap by caskdata.

the class FlowletProgramRunner method processSpecificationFactory.

private ProcessSpecificationFactory processSpecificationFactory(final BasicFlowletContext flowletContext, final DataFabricFacade dataFabricFacade, final QueueReaderFactory queueReaderFactory, final String flowletName, final Table<Node, String, Set<QueueSpecification>> queueSpecs, final ImmutableList.Builder<ConsumerSupplier<?>> queueConsumerSupplierBuilder, final SchemaCache schemaCache) {
    return new ProcessSpecificationFactory() {

        @Override
        public <T> ProcessSpecification create(Set<String> inputNames, Schema schema, TypeToken<T> dataType, ProcessMethod<T> method, ConsumerConfig consumerConfig, int batchSize, Tick tickAnnotation) throws Exception {
            List<QueueReader<T>> queueReaders = Lists.newLinkedList();
            for (Map.Entry<Node, Set<QueueSpecification>> entry : queueSpecs.column(flowletName).entrySet()) {
                for (QueueSpecification queueSpec : entry.getValue()) {
                    final QueueName queueName = queueSpec.getQueueName();
                    if (queueSpec.getInputSchema().equals(schema) && (inputNames.contains(queueName.getSimpleName()) || inputNames.contains(FlowletDefinition.ANY_INPUT))) {
                        Node sourceNode = entry.getKey();
                        if (sourceNode.getType() == FlowletConnection.Type.STREAM) {
                            ConsumerSupplier<StreamConsumer> consumerSupplier = ConsumerSupplier.create(flowletContext.getOwners(), runtimeUsageRegistry, dataFabricFacade, queueName, consumerConfig);
                            queueConsumerSupplierBuilder.add(consumerSupplier);
                            // No decoding is needed, as a process method can only have StreamEvent as type for consuming stream
                            Function<StreamEvent, T> decoder = wrapInputDecoder(flowletContext, null, queueName, new Function<StreamEvent, T>() {

                                @Override
                                @SuppressWarnings("unchecked")
                                public T apply(StreamEvent input) {
                                    return (T) input;
                                }
                            });
                            queueReaders.add(queueReaderFactory.createStreamReader(queueName.toStreamId(), consumerSupplier, batchSize, decoder));
                        } else {
                            int numGroups = getNumGroups(Iterables.concat(queueSpecs.row(entry.getKey()).values()), queueName);
                            Function<ByteBuffer, T> decoder = wrapInputDecoder(// the producer flowlet,
                            flowletContext, // the producer flowlet,
                            entry.getKey().getName(), queueName, createInputDatumDecoder(dataType, schema, schemaCache));
                            ConsumerSupplier<QueueConsumer> consumerSupplier = ConsumerSupplier.create(flowletContext.getOwners(), runtimeUsageRegistry, dataFabricFacade, queueName, consumerConfig, numGroups);
                            queueConsumerSupplierBuilder.add(consumerSupplier);
                            queueReaders.add(queueReaderFactory.createQueueReader(consumerSupplier, batchSize, decoder));
                        }
                    }
                }
            }
            // If inputs is needed but there is no available input queue, return null
            if (!inputNames.isEmpty() && queueReaders.isEmpty()) {
                return null;
            }
            return new ProcessSpecification<>(new RoundRobinQueueReader<>(queueReaders), method, tickAnnotation);
        }
    };
}
Also used : QueueReader(co.cask.cdap.app.queue.QueueReader) RoundRobinQueueReader(co.cask.cdap.internal.app.queue.RoundRobinQueueReader) Set(java.util.Set) ImmutableSet(com.google.common.collect.ImmutableSet) Schema(co.cask.cdap.api.data.schema.Schema) Node(co.cask.cdap.app.queue.QueueSpecificationGenerator.Node) ConsumerConfig(co.cask.cdap.data2.queue.ConsumerConfig) Tick(co.cask.cdap.api.annotation.Tick) QueueName(co.cask.cdap.common.queue.QueueName) StreamConsumer(co.cask.cdap.data2.transaction.stream.StreamConsumer) StreamEvent(co.cask.cdap.api.flow.flowlet.StreamEvent) ByteBuffer(java.nio.ByteBuffer) QueueConsumer(co.cask.cdap.data2.queue.QueueConsumer) TypeToken(com.google.common.reflect.TypeToken) QueueSpecification(co.cask.cdap.app.queue.QueueSpecification) Map(java.util.Map)

Example 42 with StreamEvent

use of co.cask.cdap.api.flow.flowlet.StreamEvent in project cdap by caskdata.

the class StreamClient method getEvents.

/**
 * Reads events from a stream
 *
 * @param streamId ID of the stream
 * @param start Timestamp in milliseconds or now-xs format to start reading event from (inclusive)
 * @param end Timestamp in milliseconds or now-xs format for the last event to read (exclusive)
 * @param limit Maximum number of events to read
 * @param callback Callback to invoke for each stream event read. If the callback function returns {@code false}
 *                 upon invocation, it will stops the reading
 * @throws IOException If fails to read from stream
 * @throws StreamNotFoundException If the given stream does not exists
 */
public void getEvents(StreamId streamId, String start, String end, int limit, Function<? super StreamEvent, Boolean> callback) throws IOException, StreamNotFoundException, UnauthenticatedException, UnauthorizedException {
    long startTime = TimeMathParser.parseTime(start, TimeUnit.MILLISECONDS);
    long endTime = TimeMathParser.parseTime(end, TimeUnit.MILLISECONDS);
    URL url = config.resolveNamespacedURLV3(streamId.getParent(), String.format("streams/%s/events?start=%d&end=%d&limit=%d", streamId.getStream(), startTime, endTime, limit));
    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    AccessToken accessToken = config.getAccessToken();
    if (accessToken != null) {
        urlConn.setRequestProperty(HttpHeaders.AUTHORIZATION, accessToken.getTokenType() + " " + accessToken.getValue());
    }
    if (urlConn instanceof HttpsURLConnection && !config.isVerifySSLCert()) {
        try {
            HttpRequests.disableCertCheck((HttpsURLConnection) urlConn);
        } catch (Exception e) {
        // TODO: Log "Got exception while disabling SSL certificate check for request.getURL()"
        }
    }
    try {
        if (urlConn.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
            throw new UnauthenticatedException("Unauthorized status code received from the server.");
        }
        if (urlConn.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
            throw new StreamNotFoundException(streamId);
        }
        if (urlConn.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT) {
            return;
        }
        if (urlConn.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) {
            throw new UnauthorizedException(CharStreams.toString(new InputStreamReader(urlConn.getErrorStream(), Charsets.UTF_8)));
        }
        // The response is an array of stream event object
        InputStream inputStream = urlConn.getInputStream();
        JsonReader jsonReader = new JsonReader(new InputStreamReader(inputStream, Charsets.UTF_8));
        jsonReader.beginArray();
        while (jsonReader.peek() != JsonToken.END_ARRAY) {
            Boolean result = callback.apply(GSON.<StreamEvent>fromJson(jsonReader, StreamEvent.class));
            if (result == null || !result) {
                break;
            }
        }
        drain(inputStream);
    // No need to close reader, the urlConn.disconnect in finally will close all underlying streams
    } finally {
        urlConn.disconnect();
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) StreamEvent(co.cask.cdap.api.flow.flowlet.StreamEvent) URL(java.net.URL) IOException(java.io.IOException) UnauthenticatedException(co.cask.cdap.common.UnauthenticatedException) StreamNotFoundException(co.cask.cdap.common.StreamNotFoundException) BadRequestException(co.cask.cdap.common.BadRequestException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) HttpURLConnection(java.net.HttpURLConnection) UnauthenticatedException(co.cask.cdap.common.UnauthenticatedException) AccessToken(co.cask.cdap.security.authentication.client.AccessToken) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) StreamNotFoundException(co.cask.cdap.common.StreamNotFoundException) JsonReader(com.google.gson.stream.JsonReader) HttpsURLConnection(javax.net.ssl.HttpsURLConnection)

Example 43 with StreamEvent

use of co.cask.cdap.api.flow.flowlet.StreamEvent in project cdap by caskdata.

the class StreamClientTestRun method testAsyncWrite.

/**
 * Tests for async write to stream.
 */
@Test
public void testAsyncWrite() throws Exception {
    StreamId streamId = namespaceId.stream("testAsync");
    streamClient.create(streamId);
    // Send 10 async writes
    int msgCount = 10;
    for (int i = 0; i < msgCount; i++) {
        streamClient.asyncSendEvent(streamId, "Testing " + i);
    }
    // Reads them back to verify. Needs to do it multiple times as the writes happens async.
    List<StreamEvent> events = Lists.newArrayList();
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.start();
    while (events.size() != msgCount && stopwatch.elapsedTime(TimeUnit.SECONDS) < 10L) {
        events.clear();
        streamClient.getEvents(streamId, 0, Long.MAX_VALUE, msgCount, events);
    }
    Assert.assertEquals(msgCount, events.size());
    long lastTimestamp = 0L;
    for (int i = 0; i < msgCount; i++) {
        Assert.assertEquals("Testing " + i, Charsets.UTF_8.decode(events.get(i).getBody()).toString());
        lastTimestamp = events.get(i).getTimestamp();
    }
    // No more events
    stopwatch = new Stopwatch();
    stopwatch.start();
    events.clear();
    while (events.isEmpty() && stopwatch.elapsedTime(TimeUnit.SECONDS) < 1L) {
        events.clear();
        streamClient.getEvents(streamId, lastTimestamp + 1, Long.MAX_VALUE, msgCount, events);
    }
    Assert.assertTrue(events.isEmpty());
}
Also used : StreamId(co.cask.cdap.proto.id.StreamId) StreamEvent(co.cask.cdap.api.flow.flowlet.StreamEvent) Stopwatch(com.google.common.base.Stopwatch) Test(org.junit.Test)

Example 44 with StreamEvent

use of co.cask.cdap.api.flow.flowlet.StreamEvent in project cdap by caskdata.

the class StreamClientTestRun method testStreamEvents.

/**
 * Tests for the get events call
 */
@Test
public void testStreamEvents() throws IOException, BadRequestException, StreamNotFoundException, UnauthenticatedException, UnauthorizedException {
    StreamId streamId = namespaceId.stream("testEvents");
    streamClient.create(streamId);
    // Send 5000 events
    int eventCount = 5000;
    for (int i = 0; i < eventCount; i++) {
        streamClient.sendEvent(streamId, "Testing " + i);
    }
    // Read all events
    List<StreamEvent> events = streamClient.getEvents(streamId, 0, Long.MAX_VALUE, Integer.MAX_VALUE, Lists.<StreamEvent>newArrayList());
    Assert.assertEquals(eventCount, events.size());
    for (int i = 0; i < eventCount; i++) {
        Assert.assertEquals("Testing " + i, Bytes.toString(events.get(i).getBody()));
    }
    // Read first 5 only
    events.clear();
    streamClient.getEvents(streamId, 0, Long.MAX_VALUE, 5, events);
    Assert.assertEquals(5, events.size());
    // Use the 2nd and the 3rd events time as start and end time respectively
    long startTime = events.get(1).getTimestamp();
    long endTime = events.get(2).getTimestamp() + 1;
    events.clear();
    streamClient.getEvents(streamId, startTime, endTime, Integer.MAX_VALUE, events);
    // At least read the 2nd and the 3rd event. It might read more than 2 events
    // if events are written within the same timestamp.
    Assert.assertTrue(events.size() >= 2);
    int i = 1;
    for (StreamEvent event : events) {
        Assert.assertEquals("Testing " + i, Charsets.UTF_8.decode(events.get(i - 1).getBody()).toString());
        Assert.assertTrue(event.getTimestamp() >= startTime);
        Assert.assertTrue(event.getTimestamp() < endTime);
        i++;
    }
}
Also used : StreamId(co.cask.cdap.proto.id.StreamId) StreamEvent(co.cask.cdap.api.flow.flowlet.StreamEvent) Test(org.junit.Test)

Example 45 with StreamEvent

use of co.cask.cdap.api.flow.flowlet.StreamEvent in project cdap by caskdata.

the class StreamClientTestRun method testDelete.

@Test
public void testDelete() throws Exception {
    StreamId streamId = namespaceId.stream("testDelete");
    streamClient.create(streamId);
    // Send an event and get it back
    String msg = "Test Delete";
    streamClient.sendEvent(streamId, msg);
    List<StreamEvent> events = Lists.newArrayList();
    streamClient.getEvents(streamId, 0, Long.MAX_VALUE, Integer.MAX_VALUE, events);
    Assert.assertEquals(1, events.size());
    Assert.assertEquals(msg, Charsets.UTF_8.decode(events.get(0).getBody()).toString());
    // Delete the stream
    streamClient.delete(streamId);
    // Try to get info, it should throw a StreamNotFoundException
    try {
        streamClient.getConfig(streamId);
        Assert.fail();
    } catch (StreamNotFoundException e) {
    // Expected
    }
    // Try to get events, it should throw a StreamNotFoundException
    try {
        streamClient.getEvents(streamId, 0, Long.MAX_VALUE, Integer.MAX_VALUE, events);
        Assert.fail();
    } catch (StreamNotFoundException e) {
    // Expected
    }
    // Create the stream again, it should returns empty events
    streamClient.create(streamId);
    events.clear();
    streamClient.getEvents(streamId, 0, Long.MAX_VALUE, Integer.MAX_VALUE, events);
    Assert.assertTrue(events.isEmpty());
}
Also used : StreamId(co.cask.cdap.proto.id.StreamId) StreamEvent(co.cask.cdap.api.flow.flowlet.StreamEvent) StreamNotFoundException(co.cask.cdap.common.StreamNotFoundException) Test(org.junit.Test)

Aggregations

StreamEvent (co.cask.cdap.api.flow.flowlet.StreamEvent)84 Test (org.junit.Test)65 Location (org.apache.twill.filesystem.Location)27 StreamId (co.cask.cdap.proto.id.StreamId)24 StructuredRecord (co.cask.cdap.api.data.format.StructuredRecord)19 FormatSpecification (co.cask.cdap.api.data.format.FormatSpecification)17 Schema (co.cask.cdap.api.data.schema.Schema)10 IOException (java.io.IOException)9 StreamConfig (co.cask.cdap.data2.transaction.stream.StreamConfig)8 ByteBuffer (java.nio.ByteBuffer)8 ConsumerConfig (co.cask.cdap.data2.queue.ConsumerConfig)7 StreamAdmin (co.cask.cdap.data2.transaction.stream.StreamAdmin)6 TransactionContext (org.apache.tephra.TransactionContext)6 BinaryDecoder (co.cask.cdap.common.io.BinaryDecoder)5 TypeToken (com.google.common.reflect.TypeToken)5 StreamEventCodec (co.cask.cdap.common.stream.StreamEventCodec)4 IdentityStreamEventDecoder (co.cask.cdap.data.stream.decoder.IdentityStreamEventDecoder)4 File (java.io.File)4 SchemaHash (co.cask.cdap.api.data.schema.SchemaHash)3 QueueName (co.cask.cdap.common.queue.QueueName)3