http://git-wip-us.apache.org/repos/asf/incubator-edgent-website/blob/9b42cd73/content/algolia_search.json ---------------------------------------------------------------------- diff --git a/content/algolia_search.json b/content/algolia_search.json index 3c4d280..22b4d6d 100644 --- a/content/algolia_search.json +++ b/content/algolia_search.json @@ -8,6 +8,19 @@ { +"title": "Edgent Application Development, Packaging and Execution.", +"tags": "", +"keywords": "", +"url": "../docs/application-development", +"summary": "", +"body": "To develop Edgent applications you will utilize the Edgent SDK/runtime jars and package your applicationartifacts for deploying to an edge device or gateway for execution.The Edgent SDK/runtime jars are published to the [ASF Nexus Releases Repository](https://repository.apache.org/content/repositories/releases/)and the Maven Central Repository.Alternatively, you can build the Edgent SDK yourself from a source releaseand the resulting jars will be added to your local maven repository. There are a set of Edgent jars for each supported platform: java8, java7, and android.The maven artifact groupIds for the Edgent jars are:- `org.apache.edgent` - for java8,- `org.apache.edgent.java7`- `org.apache.edgent.android`Note, the Java package names for Edgent components do not incorporatethe platform kind; the package names are the same regardless of the platform.See the release's `JAVA_SUPPORT` information in [downloads](downloads)for more information on artifact coordinates, etc.## Writing Your ApplicationThe Edgent API is most easily used by using Java8 lambda expressions.If you only want to deploy your Edgent application to a java8 environmentthen your application may use any java8 features it chooses. You compileand run against the Edgent java8 jars.If you want to deploy your Edgent application to a java7 or androidenvironment, it's still easiest to write your application using the Edgent APIswith java8 lambda expressions. You compile with java8 but constrain your application to using java7 features plus java8 lambda expressions.The Retrolambda tool is used to convert your application's generated class files to java7.The Edgent java7 and android platform jars were created in that manner too.Your application would then be run against the appropriateEdgent platform jars. Alternatively you can forgo the use of lambdaexpressions and write your application in java7 and compileand run against the appropriate Edgent platform jars.For convenience it's easiest to build your Edgent application using maven-repository-enabled build tooling (e.g., maven, maven-enabledEclipse or IntelliJ). The tooling transparently downloads the required Edgent jars from the maven repository if they aren'talready present in your local maven repository.### Edgent Application Template You can clone the `template` project as a starting point for yourEdgent application. See [Quickstart with Edgent Samples](edgent-getting-started-samples)for information about the template sample.TODO: we would like to provide a maven Edgent Application archetypethat users can use to create an application project template.### Using Non-maven-integrated ToolingIf you can't or don't want to use maven-repository-enabled toolingyou will need to get a local copy of the Edgent jars and theirdependencies and add them to your compile classpath. This caseis covered in subsequent sections.## Packaging and ExecutionEdgent doesn't provide any \"deployment\" mechanisms other than its primitive\"r egister jar\" feature (see the `IotProvider` javadoc). Generally, managingthe deployment of application and Edgent jars to edge devices is left to others (as an example, the IBM Watson IoT Platform has device APIs tosupport \"firmware\" download/update).To deploy an Edgent application to a device like a Raspberry Pi, you could just FTP the application to the device and modify thedevice to start the application upon startup or on command.Also see the `cron` folder in the Edgent samples.To run your Edgent application on an edge device, your applicationjar(s) need to be on the device. Additionally, the application's dependent Edgent jars (and their transitive dependencies) need tobe on the device. It's unlikely the device will be able to retrievethe dependencies directly from a remote maven repository such asmaven central.Here are three options for dealing with this.### Option 1: Create an uber-jar for your applicationThe uber jar is a standalone entity containingeverything that's n eeded to run your application.The uber jar contains the application's classes andthe application's dependent Edgent classes and theirtransitive dependencies.The template project's pom andthe Edgent samples poms contain configuration informationthat generates an uber jar in addition to the standardapplication jar. Eclipse can also export an uber jar.You run your application like: `java -cp `### Option 2: Separately manage the application and Edgent jarsCopy the application's jars to the device.Get a copy of the Edgent jars and their dependenciesonto the device. It's possible for multiple Edgentapplications to share the Edgent jars.The Apache Edgent project does not release abinary bundle containing all of the Edgent jarsand their dependencies. The binary artifactsare only released to maven central.See `get-edgent-jars-project/README.md` in the Edgent samples for a tool to get a copy of the Edgent jars.### Option 3: Create an application package bundleThe bundle is a standalone entity containingeverything that's needed to run your application. The bundle is copied to the device and unpacked.A run script forms the appropriate `CLASSPATH`to the package's jars and starts the application.The `package-app.sh` script included with theEdgent samples creates an application bundle.The application bundle contains the application's jar,the application's dependent Edgent jars (as specified inthe application's pom) and the Edgent jars' dependencies,and a run-app.sh script.The application's dependent Edgent runtime jars and their dependencies are retrieved from a local or remotemaven repository.If the application's execution environment isjava7 or android, use the appropriate script optionsto retrieve the appropriate Edgent platform jars forexecution.The generated run-app.sh script configures the CLASSPATHand runs the application.E.g.,``` shcd MyApp # the application's project directorypackage-app.sh --mainClass com.mycompany.app.MyApp --appjar target/my-app-1.0-SNAPS HOT.jar##### get the app specific dependencies......##### create target/app-run.sh...##### create target/app-pkg.tar...##### Copy target/app-pkg.tar to the destination system\"##### To run the app:\"##### mkdir app-pkg\"##### tar xf app-pkg.tar -C app-pkg\"##### (cd app-pkg; ./app-run.sh)\"```For more usage information:``` sh./package-app.sh -h```" + +}, + + + + +{ "title": "Committers", "tags": "", "keywords": "", @@ -65,7 +78,20 @@ "keywords": "", "url": "../docs/downloads", "summary": "", -"body": "Official Apache Edgent releases are available for download from the ASF distribution site. A release consists of a source code bundle and a convenience binary bundle. See the table below for a release's download links.If you just want to use Edgent, it is easiest to download and unpack a binary bundle. The bundle includes the release's Javadoc. The Javadoc is also accessible online. For more information, please refer to the [Getting started guide](edgent-getting-started).A source bundle contains a README describing how to build the sources.If you want to access the latest unreleased Edgent source or contribute to the Edgent runtime development, use the [GitHub repository]({{ site.data.project.source_repository_mirror }}). You can also select a particular release version by release tag (e.g., 1.0.0-incubating). See [README.md](https://github.com/apache/incubator-edgent/blob/master/README.md) and [DEVELOPMENT.md](https://github.com/apache/incubator-edgent/blob/master/DEVELOP MENT.md) in the repository for more information.See the [community](community) page for more information about contributing to Edgent development.## Apache Edgent ReleasesIt is essential that you verify the integrity of a downloaded bundle. See [how to verify]({{ site.data.downloads.generic_how_to_verify_location }}) for details on verifying using downloaded KEYS, PGP signature, MD5, or SHA information.Download the [KEYS]({{ site.data.downloads.edgent_keys_file_location }}) file for verifying a bundle's PGP signature.| Version | Date | Bundles | Release Notes | Docs | PGP | MD5 | SHA ||:-----------------:|:--------------:|:-------:|:-------------:|:----:|:---:|:---:|:-----:|| 1.1.0-incubating | 2017-03-20 | [Source]({{ site.data.downloads.edgent_1-1-0_dist_location }}) | [1.1.0 Release]({{ site.data.downloads.edgent_1-1-0_release_note }}) | [Javadoc]({{ site.data.downloads.edgent_1-1-0_doc_location }}) | [ASC]({{ site.data.downloads.edgent_1-1-0_asc_locat ion }}) | [MD5]({{ site.data.downloads.edgent_1-1-0_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-1-0_sha_location }}) || | | [Binary]({{ site.data.downloads.edgent_1-1-0_bin_dist_location }}) | | | [ASC]({{ site.data.downloads.edgent_1-1-0_bin_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-1-0_bin_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-1-0_bin_sha_location }}) || 1.0.0-incubating | 2016-12-15 | [Source]({{ site.data.downloads.edgent_1-0-0_dist_location }}) | [1.0.0 Release]({{ site.data.downloads.edgent_1-0-0_release_note }}) | [Javadoc]({{ site.data.downloads.edgent_1-0-0_doc_location }}) | [ASC]({{ site.data.downloads.edgent_1-0-0_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-0-0_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-0-0_sha_location }}) || | | [Binary]({{ site.data.downloads.edgent_1-0-0_bin_dist_location }}) | | | [ASC]({{ site.dat a.downloads.edgent_1-0-0_bin_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-0-0_bin_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-0-0_bin_sha_location }}) |" +"body": "Official ASF Apache Edgent releases consist of a single Edgent SDK/runtime source bundle and convenience binaries. Convenience binary jars for the Edgent SDK/runtime are available at the [ASF Nexus Releases Repository](https://repository.apache.org/content/repositories/releases/) and Maven Central. See [Quickstart with Edgent Samples](edgent-getting-started-samples) if you just want to use Edgent and jump-start your Edgent application development.Note, a separate binary bundle consisting of all of the Edgent runtime jars is not released. A tool is available in the samples that can create one.A source bundle contains a README describing how to build the sources.If you want to access the latest unreleased Edgent source or contribute to the Edgent runtime development, use the [GitHub repository]({{ site.data.project.source_repository_mirror }}). You can also select a particular release version by release tag (e.g., 1.0.0-incubating). See [README.md](https://github.com/apach e/incubator-edgent/blob/master/README.md) and [DEVELOPMENT.md](https://github.com/apache/incubator-edgent/blob/master/DEVELOPMENT.md) in the repository for more information.See the [community](community) page for more information about contributing to Edgent development.## Apache Edgent Releases| Version | Docs ||:-----------------:|:----:|| 1.2.0-incubating | [JAVA_SUPPORT]({{ site.data.downloads.edgent_1-2-0_java_support_doc_location }}), [Javadoc]({{ site.data.downloads.edgent_1-2-0_doc_location }}), [Samples](edgent-getting-started-samples) |It is essential that you verify the integrity of a downloaded bundle. See [how to verify]({{ site.data.downloads.generic_how_to_verify_location }}) for details on verifying using downloaded KEYS, PGP signature, MD5, or SHA information.Download the [KEYS]({{ site.data.downloads.edgent_keys_file_location }}) file for verifying a bundle's PGP signature.| Version | Date | Bundles | Release Notes | PGP | MD5 | SHA ||:-----------------:|:--------------:|:-------:|:-------------:|:---:|:---:|:-----:|| 1.2.0-incubating | 2017-12-14 | [Source]({{ site.data.downloads.edgent_1-2-0_dist_location }}) | [1.2.0 Release]({{ site.data.downloads.edgent_1-2-0_release_note }}) | [tar-ASC]({{ site.data.downloads.edgent_1-2-0_asc_location }}) | [tar-MD5]({{ site.data.downloads.edgent_1-2-0_md5_location }}) | [tar-SHA]({{ site.data.downloads.edgent_1-2-0_sha_location }}) || | | | | [zip-ASC]({{ site.data.downloads.edgent_1-2-0_zip_asc_location }}) | [zip-MD5]({{ site.data.downloads.edgent_1-2-0_zip_md5_location }}) | [zip-SHA]({{ site.data.downloads.edgent_1-2-0_zip_sha_location }}) |## Releases Prior to 1.2.0Official Apache Edgent releases are available for download from the ASF distribution site. A release consists of a source code bundle and a convenience binary bundle. See the table below for a release's download links.There is not a sepa rate samples source bundle and convenience binary jars are not distributed to the ASF Nexus Repository or Maven Central.If you just want to use Edgent, it is easiest to download and unpack a binary bundle. The bundle includes the release's Javadoc. The Javadoc is also accessible online. For more information, please refer to the [Getting started guide](edgent-getting-started).A source bundle contains a README describing how to build the sources.It is essential that you verify the integrity of a downloaded bundle. See [how to verify]({{ site.data.downloads.generic_how_to_verify_location }}) for details on verifying using downloaded KEYS, PGP signature, MD5, or SHA information.Download the [KEYS]({{ site.data.downloads.edgent_keys_file_location }}) file for verifying a bundle's PGP signature.| Version | Date | Bundles | Release Notes | Docs | PGP | MD5 | SHA ||:-----------------:|:--------------:|:-------:|:-------------:|:----:|:---:|:---:|:-----:|| 1.1.0-incuba ting | 2017-03-20 | [Source]({{ site.data.downloads.edgent_1-1-0_dist_location }}) | [1.1.0 Release]({{ site.data.downloads.edgent_1-1-0_release_note }}) | [Javadoc]({{ site.data.downloads.edgent_1-1-0_doc_location }}) | [ASC]({{ site.data.downloads.edgent_1-1-0_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-1-0_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-1-0_sha_location }}) || | | [Binary]({{ site.data.downloads.edgent_1-1-0_bin_dist_location }}) | | | [ASC]({{ site.data.downloads.edgent_1-1-0_bin_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-1-0_bin_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-1-0_bin_sha_location }}) || 1.0.0-incubating | 2016-12-15 | [Source]({{ site.data.downloads.edgent_1-0-0_dist_location }}) | [1.0.0 Release]({{ site.data.downloads.edgent_1-0-0_release_note }}) | [Javadoc]({{ site.data.downloads.edgent_1-0-0_doc_location }}) | [ASC]({{ site.data.downloads.edgent_1 -0-0_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-0-0_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-0-0_sha_location }}) || | | [Binary]({{ site.data.downloads.edgent_1-0-0_bin_dist_location }}) | | | [ASC]({{ site.data.downloads.edgent_1-0-0_bin_asc_location }}) | [MD5]({{ site.data.downloads.edgent_1-0-0_bin_md5_location }}) | [SHA]({{ site.data.downloads.edgent_1-0-0_bin_sha_location }}) |" + +}, + + + + +{ +"title": "Getting started with Apache Edgent Samples", +"tags": "", +"keywords": "", +"url": "../docs/edgent-getting-started-samples", +"summary": "", +"body": "Getting started with the Edgent samples is a great way to start using Edgent andjump-start your Edgent application development.Be sure to see _Additional Resources_ below for more great info!# QuickstartConvenience binaries (jars) for the Edgent runtime releases are distributedto the ASF Nexus Repository and the Maven Central Repository. You don't haveto manually download the Edgent jars and there is no need to download the Edgent runtime sources and build them unless you want to.By default the samples depend on Java8. Download and install Java8 if needed.## Download the Edgent SamplesGet the Edgent Samples either by cloning or downloading the [Edgent Samples GitHub repository](https://github.com/apache/incubator-edgent-samples):```shgit clone https://github.com/apache/incubator-edgent-samplescd incubator-edgent-samplesgit checkout develop```or to download: + Open the _Clone or download_ pulldown at the [Edgent Samples GitHub repository](https://github.com/apache/incubat or-edgent-samples) + Click on _Download ZIP_ + Unpack the downloaded ZIP```sh unzip incubator-edgent-samples-develop.zip```## Build the Samples```shcd ./mvnw clean package # build for Java8```## Run the HelloEdgent sample```shcd topology./run-sample.sh HelloEdgent # prints a hello message and terminates Hello Edgent! ...```# Additional ResourcesSee [The Power of Edgent](power-of-edgent) to help you quickly start to get a sense of Edgent's capabilities.See the [Getting Started Guide](edgent-getting-started) for a tutorial.Much more information about the samples is available in the README.md at the [Edgent Samples GitHub repository](https://github.com/apache/incubator-edgent-samples), including: + application development and packaging + application template project + list of samples + using an IDE" }, @@ -78,7 +104,7 @@ "keywords": "", "url": "../docs/edgent-getting-started", "summary": "", -"body": "## What is Apache Edgent?Edgent is an open source programming model and runtime for edge devices that enables you to analyze streaming data on your edge devices. When you analyze on the edge, you can:* Reduce the amount of data that you transmit to your analytics server* Reduce the amount of data that you storeFor more information, see the [Edgent overview](home).### Apache Edgent and streaming analyticsThe fundamental building block of an Edgent application is a **stream**: a continuous sequence of tuples (messages, events, sensor readings, and so on).The Edgent API provides the ability to process or analyze each tuple as it appears on a stream, resulting in a derived stream.Source streams are streams that originate data for analysis, such as readings from a device's temperature sensor.Streams are terminated using sink functions that can perform local device control or send information to centralized analytic systems through a message hub.Edgent's primary API is functional where streams are sourced, transformed, analyzed or sinked though functions, typically represented as lambda expressions, such as `reading -> reading 80` to filter temperature readings in Fahrenheit.### Downloading Apache EdgentTo use Edgent, you need the Edgent JAR files, which you may obtain by completing the following steps.1. Locate the Edgent release you would like to use on the [downloads page]({{ site.data.project.download }})2. In the Bundles column for the desired release: * Click on the _Binary_ link if you simply want to use Edgent. This is the easiest method is to get up and running as it contains a pre-built version of Edgent. * Click on the _Source_ link if you would like access to the Edgent source files. If you choose this method, you must manually build Edgent yourself.3. Download the .tgz file from one of the mirror sites4. Unpack the downloaded file: `tar zxvf apache-edgent-X.X.X-incubating-XXX.tgz`5. Obtain the JARs * If you are using a binary bundle, then the Java 8 JARs are located in `edgent-X.X.X/java8` * If you are using a source bundle, build the source code: 1. Install [Gradle](https://gradle.org/) if it is not yet installed 2. Navigate to the unpacked directory: `cd edgent-X.X.X-src` 3. Run `gradle` to initialize the Gradle wrapper 4. Build the code and Javadoc: `./gradlew assemble` 5. The Java 8 JARs are located in `edgent-X.X.X-src/build/distributions/java8`### Setting up your environmentEnsure that you are running a supported environment. For more information, see the [Edgent overview](home). This guide assumes you're running Java 8. The Edgent Java 8 JAR files are located in either the `edgent-X.X.X/java8` or `edgent-X.X.X-src/build/distributions/java8` directory, depending on whether you downloaded a binary or source bundle.1. Create a new Java project in Eclipse, and specify Java 8 as the execution environment JRE: 2. Include one or more Edgent JARs in your project's build pa th depending on what features your application uses: 1. Include one or more of the topology providers: * `java8/lib/edgent.providers.development.jar` (if using the [DevelopmentProvider]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/development/DevelopmentProvider.html)) * `java8/lib/edgent.providers.direct.jar`(if using the [DirectProvider]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html)) * `java8/lib/edgent.providers.iot.jar` (if using the [IotProvider]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/iot/IotProvider.html)) 2. Include the JARs for any Edgent connectors or analytic features you use in `java8/connectors` and `java8/analytics`, respectively 3. Include the JARs for any Edgent utility features you use: * `java8/utils/metrics/lib/edgent.utils.metrics.jar` (for the [org.apache.edgent.metrics]({{ site.docsurl }}/org/apache/{{ site. data.project.unix_name }}/metrics/package-summary.html) package) * `java8/utils/streamscope/lib/edgent.utils.streamscope.jar` (for the [org.apache.edgent.streamscope]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/streamscope/package-summary.html) package) 4. Include the JAR for the [java.util.logging](https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html) framework for [SLF4J](https://www.slf4j.org/): `java8/ext/slf4j-jdk14-X.X.X.jar` Your environment is set up! You can start writing your first Edgent application.## Creating a simple applicationIf you're new to Edgent or to writing streaming applications, the best way to get started is to write a simple program.Edgent is a framework that pushes data analytics and machine learning to *edge devices*. (Edge devices include things like routers, gateways, machines, equipment, sensors, appliances, or vehicles that are connected to a network.) Edgent enables you to process data loca lly—such as, in a car engine, on an Android phone, or on a Raspberry Pi—before you send data over a network.For example, if your device takes temperature readings from a sensor 1,000 times per second, it is more efficient to process the data locally and send only interesting or unexpected results over the network. To simulate this, let's define a (simulated) TempSensor class:```javaimport java.util.Random;import org.apache.edgent.function.Supplier;/** * Every time get() is called, TempSensor generates a temperature reading. */public class TempSensor implements Supplier { double currentTemp = 65.0; Random rand; TempSensor(){ rand = new Random(); } @Override public Double get() { // Change the current temperature some random amount double newTemp = rand.nextGaussian() + currentTemp; currentTemp = newTemp; return currentTemp; }}```Every time you call `TempSensor.get()`, it returns a new temperature reading. The continu ous temperature readings are a stream of data that an Edgent application can process.Our sample Edgent application processes this stream by filtering the data and printing the results. Let's define a TempSensorApplication class for the application:```javaimport java.util.concurrent.TimeUnit;import org.apache.edgent.providers.direct.DirectProvider;import org.apache.edgent.topology.TStream;import org.apache.edgent.topology.Topology;public class TempSensorApplication { public static void main(String[] args) throws Exception { TempSensor sensor = new TempSensor(); DirectProvider dp = new DirectProvider(); Topology topology = dp.newTopology(); TStream tempReadings = topology.poll(sensor, 1, TimeUnit.MILLISECONDS); TStream filteredReadings = tempReadings.filter(reading -> reading 80); filteredReadings.print(); dp.submit(topology); }}```To understand how the application processes the stream, let's review each line.### Specifying a pro viderYour first step when you write an Edgent application is to create a [`DirectProvider`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html):```javaDirectProvider dp = new DirectProvider();```A `Provider` is an object that contains information on how and where your Edgent application will run. A `DirectProvider` is a type of Provider that runs your application directly within the current virtual machine when its [`submit()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html#submit-org.apache.{{ site.data.project.unix_name }}.topology.Topology-) method is called.### Creating a topologyAdditionally, a Provider is used to create a [`Topology`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/Topology.html) instance:```javaTopology topology = dp.newTopology();```In Edgent, `Topology` is a container that describes the structure of your appl ication:* Where the streams in the application come from* How the data in the stream is modifiedIn the TempSensorApplication class above, we have exactly one data source: the `TempSensor` object. We define the source stream by calling [`topology.poll()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/Topology.html#poll-org.apache.{{ site.data.project.unix_name }}.function.Supplier-long-java.util.concurrent.TimeUnit-), which takes both a [`Supplier`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/function/Supplier.html) function and a time parameter to indicate how frequently readings should be taken. In our case, we read from the sensor every millisecond:```javaTStream tempReadings = topology.poll(sensor, 1, TimeUnit.MILLISECONDS);```### Defining the `TStream` objectCalling `topology.poll()` to define a source stream creates a `TStream` instance, which represents the series of readings taken from the temperature sensor.A streamin g application can run indefinitely, so the [`TStream`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/TStream.html) might see an arbitrarily large number of readings pass through it. Because a `TStream` represents the flow of your data, it supports a number of operations which allow you to modify your data.### Filtering a `TStream`In our example, we want to filter the stream of temperature readings, and remove any \"uninteresting\" or expected readings—specifically readings which are above 50 degrees and below 80 degrees. To do this, we call the `TStream`'s [`filter`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#filter-org.apache.{{ site.data.project.unix_name }}.function.Predicate-) method and pass in a function that returns *true* if the data is interesting and *false* if the data is uninteresting:```javaTStream filteredReadings = tempReadings.filter(reading -> reading 80);```As you can see, the f unction that is passed to `filter` operates on each tuple individually. Unlike data streaming frameworks like [Apache Spark](https://spark.apache.org/), which operate on a collection of data in batch mode, Edgent achieves low latency processing by manipulating each piece of data as soon as it becomes available. Filtering a `TStream` produces another `TStream` that contains only the filtered tuples; for example, the `filteredReadings` stream.### Printing to outputWhen our application detects interesting data (data outside of the expected parameters), we want to print results. You can do this by calling the [`TStream.print()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#print--) method, which prints using `.toString()` on each tuple that passes through the stream:```javafilteredReadings.print();```Unlike `TStream.filter()`, `TStream.print()` does not produce another `TStream`. This is because `TStream.print()` is a **sink**, which represents the terminus of a stream.In addition to `TStream.print()` there are other sink operations that send tuples to an MQTT server, JDBC connection, file, or Kafka cluster. Additionally, you can define your own sink by invoking [`TStream.sink()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#sink-org.apache.{{ site.data.project.unix_name }}.function.Consumer-) and passing in your own function.### Submitting your applicationNow that your application has been completely declared, the final step is to run your application.`DirectProvider` contains a `submit()` method, which runs your application directly within the current virtual machine:```javadp.submit(topology);```After you run your program, you should see output containing only \"interesting\" data coming from your sensor:```49.90403231177259647.9783750403908446.5927233630903146.68154455165293447.400819234155236...```As you can see, all temperatures are outside the 50-80 degree range. In terms of a real-world application, this would prevent a device from sending superfluous data over a network, thereby reducing communication costs.## Further examplesThis example demonstrates a small piece of Edgent's functionality. Edgent supports more complicated topologies, such as topologies that require merging and splitting data streams, or perform operations which aggregate the last *N* seconds of data (for example, calculating a moving average).For more complex examples, see:* [Edgent sample programs](samples)* [Stream processing concepts](streaming-concepts)* [Common Edgent operations](common-edgent-operations)" +"body": "## What is Apache Edgent?Edgent is an open source programming model and runtime for edge devices that enables you to analyze streaming data on your edge devices. When you analyze on the edge, you can:* Reduce the amount of data that you transmit to your analytics server* Reduce the amount of data that you storeEdgent accellerates your development of applications to push data analytics and machine learning to *edge devices*. (Edge devices include things like routers, gateways, machines, equipment, sensors, appliances, or vehicles that are connected to a network.) Edgent applications process data locally—such as, in a car, on an Android phone, or on a Raspberry Pi—before it sends data over a network.For example, if your device takes temperature readings from a sensor 1,000 times per second, it is more efficient to process the data locally and send only interesting or unexpected results over the network.See [The Power of Edgent](power-of-edgent) to help you quickly start to get a sense of Edgent's capabilities.Releases of Edgent prior to 1.2.0 distributed Edgent and the samples differently than today. See [Old Getting Started](old-edgent-getting-started) if you are trying to use an older version.There's a lot of information available to get started with Edgent and no \"best order\" for navigating it. See the navigation sidebar on the left hand side of this page. In particular it is recommended that you review and visit the various items under _Get Started_.If you want to get a developent environment setup quickly see the [Quickstart with Edgent Samples](edgent-getting-started-samples) item. The _Edgent Cookbook_ topic includes many well documented recipies that are good for learning and jump-starting the development of your application.The rest of this page is a detailed introduction to Edgent using a simple simulated Temperature Sensor application.## Apache Edgent and streaming analyticsThe fundamental building block of an Edgent applicat ion is a **stream**: a continuous sequence of tuples (messages, events, sensor readings, and so on).The Edgent API provides the ability to process or analyze each tuple as it appears on a stream, resulting in a derived stream.Source streams are streams that originate data for analysis, such as readings from a device's temperature sensor.Streams are terminated using sink functions that can perform local device control or send information to external services such as centralized analytic systems through a message hub.Edgent's primary API is functional where streams are sourced, transformed, analyzed or sinked though functions, typically represented as Java8 lambda expressions, such as `reading -> reading 80` to filter temperature readings in Fahrenheit.A **topology** is a graph of streams and their processing transformations. A **provider** is a factory for creating and executing topologies.Basic Edgent Applications follow a common structure: 1. Get a provider 2. Create the topolog y and compose its processing graph 3. Submit the topology for executionMore sophisticated applications may consist of multiple topologies that may be dynamically created and started and stopped using commands from external applications.## Temperature Sensor ApplicationIf you're new to Edgent or to writing streaming applications, the best way to get started is to write a simple program.First we'll go over the details of the application, then we'll run it.Let's create a simple Temperature Sensor Application. The application takes temperature readings from a sensor 1,000 times per second. Instead of reporting each reading, it is more efficient to process the data locally and send only interesting or unexpected results over the network.To simulate this, let's define a (simulated) TempSensor class:```javaimport java.util.Random;import org.apache.edgent.function.Supplier;public class TempSensor implements Supplier { double currentTemp = 65.0; Random rand; TempSensor(){ r and = new Random(); } @Override public Double get() { // Change the current temperature some random amount double newTemp = rand.nextGaussian() + currentTemp; currentTemp = newTemp; return currentTemp; }}```Every time `TempSensor.get()` is called, it returns a new temperature reading.Our application composes a topology that creates a continuous stream of temperature readings and processes this stream by filtering the data and printing the results. Let's define a TempSensorApplication class for the application:```javaimport java.util.concurrent.TimeUnit;import org.apache.edgent.providers.direct.DirectProvider;import org.apache.edgent.topology.TStream;import org.apache.edgent.topology.Topology;public class TempSensorApplication { public static void main(String[] args) throws Exception { TempSensor sensor = new TempSensor(); DirectProvider dp = new DirectProvider(); Topology topology = dp.newTopology(); TStream temp Readings = topology.poll(sensor, 1, TimeUnit.MILLISECONDS); TStream filteredReadings = tempReadings.filter(reading -> reading 80); filteredReadings.print(); dp.submit(topology); }}```Let's review each line.### Specifying a providerYour first step when you write an Edgent application is to create a _Provider_. In this case we're using a [DirectProvider]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html):```javaDirectProvider dp = new DirectProvider();```A `Provider` is an object that contains information on how and where your Edgent application will run. A `DirectProvider` is a type of Provider that runs your application directly within the current virtual machine when its [submit()]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html#submit-org.apache.{{ site.data.project.unix_name }}.topology.Topology-) method is called.The [IotProvider]({{ site.d ocsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/providers/iot/IotProvider.html) is an alternative that offers very useful and powerful capabilities.### Creating a topologyThe Provider is used to create a [Topology]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/Topology.html) instance:```javaTopology topology = dp.newTopology();```In Edgent, `Topology` is a container that describes the structure of your processing graph:* Where the streams in the application come from* How the data in the stream is modifiedOur application then composes the topology's progessing graph.### Creating a source `TStream`In the `TempSensorApplication` class above, we have exactly one data source: the `TempSensor` object. We define the source stream by calling [topology.poll()]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/Topology.html#poll-org.apache.{{ site.data.project.unix_name }}.function.Supplier-long-java.util.concurre nt.TimeUnit-), which takes both a [Supplier]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/function/Supplier.html) function and a time parameter to indicate how frequently readings should be taken. In our case, we read from the sensor every millisecond:```javaTStream tempReadings = topology.poll(sensor, 1, TimeUnit.MILLISECONDS);```Calling `topology.poll()` to define a source stream creates a `TStream` instance (because `TempSensor.get()` returns a `Double`), which represents the series of readings taken from the temperature sensor.A streaming application can run indefinitely, so the [TStream]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/TStream.html) might see an arbitrarily large number of readings pass through it. Because a `TStream` represents the flow of your data, it supports a number of operations which allow you to modify your data.### Filtering a `TStream`In our example, we want to filter the stream of temp erature readings, and remove any \"uninteresting\" or expected readings—specifically readings which are above 50 degrees and below 80 degrees. To do this, we call the `TStream`'s [filter]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#filter-org.apache.{{ site.data.project.unix_name }}.function.Predicate-) method and pass in a function that returns *true* if the data is interesting and *false* if the data is uninteresting:```javaTStream filteredReadings = tempReadings.filter(reading -> reading 80);```As you can see, the function that is passed to `filter` operates on each tuple individually. Unlike data streaming frameworks like [Apache Spark](https://spark.apache.org/), which operate on a collection of data in batch mode, Edgent achieves low latency processing by manipulating each piece of data as soon as it becomes available. Filtering a `TStream` produces another `TStream` that contains only the filtered tuples; in this case, the `fil teredReadings` stream.### Printing to outputWhen our application detects interesting data (data outside of the expected parameters), we want to print results. You can do this by calling the [TStream.print()]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#print--) method, which prints using `.toString()` on each tuple that passes through the stream:```javafilteredReadings.print();```Unlike `TStream.filter()`, `TStream.print()` does not produce another `TStream`. This is because `TStream.print()` is a **sink**, which represents the terminus of a stream.A real application typically publishes results to an MQTT server, IoT Hub, Kafka cluster, file, JDBC connection, or other external system. Edgent comes easy to use connectors for these. See the _connectors_ samples, [Edgent Javadoc]({{ site.docsurl }}), and _Edgent Cookbook_ for more information.You can define your own sink by invoking [TStream.sink()]({{ site.docsurl }}/org/apache/{{ site.data.pr oject.unix_name }}/topology/TStream.html#sink-org.apache.{{ site.data.project.unix_name }}.function.Consumer-) and passing in your own function.### Submitting your topologyNow that your topology / processing graph has been completely declared, the final step is to run it.`DirectProvider` contains a `submit()` method, which runs a topology directly within the current virtual machine:```javadp.submit(topology);```After you run your program, you should see output containing only \"interesting\" data coming from your sensor:```49.90403231177259647.9783750403908446.5927233630903146.68154455165293447.400819234155236...```As you can see, all temperatures are outside the 50-80 degree range. In terms of a real-world application, this would prevent a device from sending superfluous data over a network, thereby reducing communication costs.### Building and RunningIts easiest to use the Edgent Samples Source release to get started.If you just want to see this application in action, it's one of the provided samples!Go to [Getting Started with Samples](edgent-getting-started-samples) to get and build the samples.Then you can run this application from the command line:```shcd cd topology; ./run-sample.sh TempSensorApplication 46.59272336309031 46.681544551652934 ...^C to terminate it```If you setup an Eclipse workspace with the samples, you can run the application from Eclipse:1. From the Eclipse *Navigate* menu, select *Open Type* + enter type type name `TempSensorApplication` and click *OK*2. right click on the `TempSensorApplication` class name and from the context menu + click on *Run As*, then *Java application*. `TempSensorApplication` runs and prints to the Console view. Click on the `terminate` control in the Console view to stop the application.### Creating your own projectIn this flow we'll take you though creating a new project for this application.Its easiest to use the `template` project in the Edgent Samples to get started.Go to [Getting Started wi th Samples](edgent-getting-started-samples) and follow the steps to * do the general samples setup * clone the `template` project to use for this applicationThen create the `TempSensor.java` and `TempSensorApplication.java` files in the project, copying in the above code.To build and run from the command line, see the new project's README.md (copied in from the template).In the project's folder (adjust the package name below if appropriate)```sh./mvnw clean package./app-run.sh --main com.mycompany.app.TempSensorApplication 46.59272336309031 46.681544551652934 ...^C to terminate it```If you setup the cloned template in an Eclipse workspace:1. From the Eclipse *Navigate* menu, select *Open Type* + enter type type name `TempSensorApplication` and click *OK*2. right click on the `TempSensorApplication` class name and from the context menu + click on *Run As*, then *Java application*. `TempSensorApplication` runs and prints to the Console view. Click on the `terminate` con trol in the Console view to stop the application.## Next StepsThis introduction demonstrates a small piece of Edgent's functionality. Edgent supports more complicated topologies, such as topologies that require merging and splitting data streams, or perform operations which aggregate the last *N* seconds of data (for example, calculating a moving average). Typically your application will want to publish to an IoT hub and be controlled by applications in a data center.There are many more useful resources under the _Get Started_ and _Edgent Cookbook_ topics in the navigation sidebar on the left hand side of this page." }, @@ -104,7 +130,7 @@ "keywords": "", "url": "../docs/faq", "summary": "", -"body": "## What is Apache Edgent?Edgent provides APIs and a lightweight runtime to analyze streaming data at the edge.## What do you mean by the edge?The edge includes devices, gateways, equipment, vehicles, systems, appliances and sensors of all kinds as part of the Internet of Things.## How is Apache Edgent used?Edgent can be used at the edge of the Internet of Things, for example, to analyze data on devices, engines, connected cars, etc. Edgent could be on the device itself, or a gateway device collecting data from local devices. You can write an edge application on Edgent and connect it to a Cloud service, such as the IBM Watson IoT Platform. It can also be used for enterprise data collection and analysis; for example log collectors, application data, and data center analytics.## How are applications developed?Applications are developed using a functional flow API to define operations on data streams that are executed as a graph of \"oplets\" in a lightweight embeddable runtime . The SDK provides capabilities like windowing, aggregation and connectors with an extensible model for the community to expand its capabilities.## What APIs does Apache Edgent support?Currently, Edgent supports APIs for Java and Android. Support for additional languages, such as Python, is likely as more developers get involved. Please consider joining the Edgent open source development community to accelerate the contributions of additional APIs.## What type of analytics can be done with Apache Edgent?Edgent provides windowing, aggregation and simple filtering. It uses Apache Common Math to provide simple analytics aimed at device sensors. Edgent is also extensible, so you can call existing libraries from within your Edgent application. In the future, Edgent will include more analytics, either exposing more functionality from Apache Common Math, other libraries or hand-coded analytics.## What connectors does Apache Edgent support?Edgent supports connectors for MQTT, HTTP, JDBC, Fi le, Apache Kafka and IBM Watson IoT Platform. Edgent is extensible; you can add the connector of your choice.## What centralized streaming analytic systems does Apache Edgent support?Edgent supports open source technology (such as Apache Spark, Apache Storm, Flink and samza), IBM Streams (on-premises or IBM Streaming Analytics on Bluemix), or any custom application of your choice.## Why do I need Apache Edgent on the edge, rather than my streaming analytic system?Edgent is designed for the edge, rather than a more centralized system. It has a small footprint, suitable for running on devices. Edgent provides simple analytics, allowing a device to analyze data locally and to only send to the centralized system if there is a need, reducing communication costs.## Why do I need Apache Edgent, rather than coding the complete application myself?Edgent is a tool for edge analytics that allows you to be more productive. Edgent provides a consistent data model (streams and windows) and provid es useful functionality, such as aggregations, joins, etc. Using Edgent lets you to take advantage of this functionality, allowing you to focus on your application needs.## Where can I download Apache Edgent?Releases include source code and convenience binary bundles. The source code is also available on GitHub. The [downloads]({{ site.data.project.download }}) page has all of the details.## How do I get started?Getting started is simple. Once you have downloaded Edgent, everything you need to know to get up and running, you will find [here](edgent-getting-started). We suggest you also run the [Edgent sample programs](samples) to familiarize yourselves with the code base.## How can I get involved?We would love to have your help! Visit [Get Involved](community) to learn more about how to get involved.## How can I contribute code?Just submit a [pull request]({{ site.data.project.source_repository_mirror }}/pulls) and wait for a committer to review. For more information, visit our [c ommitter page](committers) and read [DEVELOPMENT.md]({{ site.data.project.source_repository_mirror }}/blob/master/DEVELOPMENT.md) at the top of the code tree.## Can I become a committer?Read about Edgent committers and how to become a committer [here](committers).## Can I take a copy of the code and fork it for my own use?Yes. Edgent is available under the Apache 2.0 license which allows you to fork the code. We hope you will contribute your changes back to the Edgent community.## How do I suggest new features?Click [Issues](https://issues.apache.org/jira/browse/{{ site.data.project.jira }}) to submit requests for new features. You may browse or query the Issues database to see what other members of the Edgent community have already requested.## How do I submit bug reports?Click [Issues](https://issues.apache.org/jira/browse/{{ site.data.project.jira }}) to submit a bug report.## How do I ask questions about Apache Edgent?Use the [dev list](mailto:{{ site.data.project.dev_list }}) t o submit questions to the Edgent community.## Why is Apache Edgent open source?With the growth of the Internet of Things there is a need to execute analytics at the edge. Edgent was developed to address requirements for analytics at the edge for IoT use cases that were not addressed by central analytic solutions. These capabilities will be useful to many organizations and that the diverse nature of edge devices and use cases is best addressed by an open community. Our goal is to develop a vibrant community of developers and users to expand the capabilities and real-world use of Edgent by companies and individuals to enable edge analytics and further innovation for the IoT space.## I see references to \"Quarks.\" How does it relate to Apache Edgent?Up until July 2016, Edgent was known as Quarks. Quarks was renamed due to the name not being unique enough." +"body": "## What is Apache Edgent?Edgent provides APIs and a lightweight runtime enabling you to easily create event-driven flow-graph style applications to analyze streaming data at the edge. Check out [The Power of Edgent](power-of-edgent) to help you guickly gain an appreciation of how Edgent can help you.## What do you mean by the edge?The edge includes devices, gateways, equipment, vehicles, systems, appliances and sensors of all kinds as part of the Internet of Things.It's easy for for Edgent applications to connect to other entities such as an enterprise IoT hub.While Edgent's design center is executing on constrained edge devices, Edgent applications can run on any system meeting minimal requirements such as a Java runtime.## How are applications developed?Applications are developed using a functional flow API to define operations on data streams that are executed as a flow graph in a lightweight embeddable runtime. Edgent provides capabilities like windowing, aggregation an d connectors with an extensible model for the community to expand its capabilities. Check out [The Power of Edgent](power-of-edgent)!You can develop Edgent applications using an IDE of your choice. Generally, mechanisms for deploying an Edgent application to a device are beyond the scope of Edgent; they are often device specific or may be defined by an enterprise IoT system. To deploy an Edgent application to a device like a Raspberry Pi, you could just FTP the application to the device and modify the device to start the application upon startup or on command. See [Edgent application Development](application-development).## What environments does Apache Edgent support?Currently, Edgent provides APIs and runtime for Java and Android. Support for additional languages, such as Python, is likely as more developers get involved. Please consider joining the Edgent open source development community to accelerate the contributions of additional APIs.## What type of analytics can be done with Apache Edgent?The core Edgent APIs make it easy to incorporate any analytics you want into the stream processing graph. It's trivial to create windows and trigger aggregation functions you supply. It's trivial to specify whatever filtering and transformation functions you want to supply. The functions you supply can use existing libraries.Edgent comes with some initial analytics for aggregation and filtering that you may find useful. It uses Apache Common Math to provide simple analytics aimed at device sensors. In the future, Edgent will include more analytics, either exposing more functionality from Apache Common Math, other libraries or hand-coded analytics.## What connectors does Apache Edgent support?Edgent provides easy to use connectors for MQTT, HTTP, JDBC, File, Apache Kafka and IBM Watson IoT Platform. Edgent is extensible; you can create connectors. You can easily supply any code you want for ingesting data from and sinking data to external systems. See [EDGENT-368 ](https://issues.apache.org/jira/browse/EDGENT-368) for a full code sample of publishing to Elasticsearch.## Does Edgent have a Sensor Library?No, Edgent does not come with a library for accessing a device's sensors. The simplicity with which an Edgent application can poll or otherwise use existing APIs for reading a sensor value make such a library unnecessary.## What centralized streaming analytic systems does Apache Edgent support?Edgent applications can publish and subscribe to message systems like MQTT or Kafka, or IoT Hubs like IBM Watson IoT Platform. Centralized streaming analytic systems can do likewise to then consume Edgent application events and data, as well as control an Edgent application. The centralized streaming analytic system could be Apache Spark, Apache Storm, Flink and Samza, IBM Streams (on-premises or IBM Streaming Analytics on Bluemix), or any custom application of your choice.## Is there a distributed version of Edgent?The short answer is that a single Edgent application's topologies all run in the same local JVM. But sometimes this question is really asking \"Can separate Edgent topologies communicate with each other?\" and the answer to that is YES!Today, multiple topologies in a single Edgent application/JVM can communicate using the Edgent PublishSubscribe connector, or any other shared resource you choose to use (e.g., a java.util.concurrent.BlockingQueue).Edgent topologies in separate JVM's, or the same JVM, can communicate with each other by using existing connectors to a local or remote MQTT server for example.## Why do I need Apache Edgent on the edge, rather than my streaming analytic system?Edgent is designed for the edge. It has a small footprint, suitable for running on constrained devices. Edgent applications can analyze data on the edge and to only send to the centralized system if there is a need, reducing communication costs.## Why do I need Apache Edgent, rather than coding the complete application myself?Edgent is designed to accelerate your development of edge analytic applications - to make you more productive! Edgent provides a simple yet powerful consistent data model (streams and windows) and provides useful functionality, such as aggregations, joins, and connectors. Using Edgent lets you to take advantage of this functionality, allowing you to focus on your application needs. Check out [The Power of Edgent](power-of-edgent) to get a better appreciation of how Edgent can help you.## Where can I download Apache Edgent?Releases include Edgent samples source code and Edgent API and runtime source code. Convenience binaries are released to Maven Central. The source code is also available on GitHub. The [downloads]({{ site.data.project.download }}) page has all of the details.## How do I get started?Getting started is simple. See [Quickstart with Edgent Samples](edgent-getting-started-samples) to jump right in or see the [Getting Started Guide](edgent-getting-started) if you prefer a bit of an introduction and tutorial first.## How can I get involved?We would love to have your help! Visit [Get Involved](community) to learn more about how to get involved.## How can I contribute code?Just submit a [pull request]({{ site.data.project.source_repository_mirror }}/pulls) and wait for a committer to review. For more information, visit our [committer page](committers) and read [DEVELOPMENT.md]({{ site.data.project.source_repository_mirror }}/blob/master/DEVELOPMENT.md) at the top of the code tree.## Can I become a committer?Read about Edgent committers and how to become a committer [here](committers).## Can I take a copy of the code and fork it for my own use?Yes. Edgent is available under the Apache 2.0 license which allows you to fork the code. We hope you will contribute your changes back to the Edgent community.## How do I suggest new features?Click [Issues](https://issues.apache.org/jira/browse/{{ site.data.project.jira }}) to submit requests for new features. You may browse or query the Issues database to see what other members of the Edgent community have already requested.## How do I submit bug reports?Click [Issues](https://issues.apache.org/jira/browse/{{ site.data.project.jira }}) to submit a bug report.## How do I ask questions about Apache Edgent?Use the [dev list](mailto:{{ site.data.project.dev_list }}) to submit questions to the Edgent community.## Why is Apache Edgent open source?With the growth of the Internet of Things there is a need to execute analytics at the edge. Edgent was developed to address requirements for analytics at the edge for IoT use cases that were not addressed by central analytic solutions. These capabilities will be useful to many organizations and that the diverse nature of edge devices and use cases is best addressed by an open community. Our goal is to develop a vibrant community of developers and users to expand the capabilities and real-world use of Edgent by companies and individuals to enable edge anal ytics and further innovation for the IoT space.## I see references to \"Quarks.\" How does it relate to Apache Edgent?Up until July 2016, Edgent was known as Quarks. Quarks was renamed due to the name not being unique enough." }, @@ -112,12 +138,12 @@ { -"title": "Introduction", -"tags": "getting_started", +"title": "Apache Edgent Overview", +"tags": "", "keywords": "", "url": "../docs/home", "summary": "", -"body": "## Apache Edgent overviewDevices and sensors are everywhere, and more are coming online every day. You need a way to analyze all of the data coming from your devices, but it can be expensive to transmit all of the data from a sensor to your central analytics engine.Edgent is an open source programming model and runtime for edge devices that enables you to analyze data and events at the device. When you analyze on the edge, you can:* Reduce the amount of data that you transmit to your analytics server* Reduce the amount of data that you storeAn Edgent application uses analytics to determine when data needs to be sent to a back-end system for further analysis, action, or storage. For example, you can use Edgent to determine whether a system is running outside of normal parameters, such as an engine that is running too hot.If the system is running normally, you donât need to send this data to your back-end system; itâs an added cost and an additional load on your system to process and store. However, if Edgent detects an issue, you can transmit that data to your back-end system to determine why the issue is occurring and how to resolve the issue.Edgent enables you to shift from sending a continuous flow of trivial data to the server to sending only essential and meaningful data as it occurs. This is especially important when the cost of communication is high, such as when using a cellular network to transmit data, or when bandwidth is limited.The following use cases describe the primary situations in which you would use Edgent:* **Internet of Things (IoT)**: Analyze data on distributed edge devices and mobile devices to: - Reduce the cost of transmitting data - Provide local feedback at the devices* **Embedded in an application server instance**: Analyze application server error logs in real time without impacting network traffic* **Server rooms and machine rooms**: Analyze machine health in real time without impacting network traffic or when bandw idth is limited### Deployment environmentsThe following environments have been tested for deployment on edge devices:* Java 8, including Raspberry Pi B and Pi2 B* Java 7* Android### Edge devices and back-end systemsYou can send data from an Apache Edgent application to your back-end system when you need to perform analysis that cannot be performed on the edge device, such as:* Running a complex analytic algorithm that requires more resources, such as CPU or memory, than are available on the edge device* Maintaining large amounts of state information about a device, such as several hours worth of state information for a patientâs medical device* Correlating data from the device with data from other sources, such as: - Weather data - Social media data - Data of record, such as a patientâs medical history or trucking manifests - Data from other devicesEdgent communicates with your back-end systems through the following message hubs:* MQTT â The messaging standard for IoT* IBM Watson IoT Platform â A cloud-based service that provides a device model on top of MQTT* Apache Kafka â An enterprise-level message bus* Custom message hubsYour back-end systems can also use analytics to interact with and control edge devices. For example:* A traffic alert system can send an alert to vehicles that are heading towards an area where an accident occurred* A vehicle monitoring system can reduce the maximum engine revs to reduce the chance of failure before the next scheduled service if it detects patterns that indicate a potential problem" +"body": "Devices and sensors are everywhere, and more are coming online every day. You need a way to analyze all of the data coming from your devices, but it can be expensive to transmit all of the data from a sensor to your central analytics engine.Edgent is an open source programming model and runtime for edge devices that enables you to analyze data and events at the device. When you analyze on the edge, you can:* Reduce the amount of data that you transmit to your analytics server* Reduce the amount of data that you storeAn Edgent application uses analytics to determine when data needs to be sent to a back-end system for further analysis, action, or storage. For example, you can use Edgent to determine whether a system is running outside of normal parameters, such as an engine that is running too hot.If the system is running normally, you donât need to send this data to your back-end system; itâs an added cost and an additional load on your system to process and store. Howev er, if Edgent detects an issue, you can transmit that data to your back-end system to determine why the issue is occurring and how to resolve the issue.Edgent enables you to shift from sending a continuous flow of trivial data to the server to sending only essential and meaningful data as it occurs. This is especially important when the cost of communication is high, such as when using a cellular network to transmit data, or when bandwidth is limited.The following use cases describe the primary situations in which you would use Edgent:* **Internet of Things (IoT)**: Analyze data on distributed edge devices and mobile devices to: - Reduce the cost of transmitting data - Provide local feedback at the devices* **Embedded in an application server instance**: Analyze application server error logs in real time without impacting network traffic* **Server rooms and machine rooms**: Analyze machine health in real time without impacting network traffic or when bandwidth is limited### Deploy ment environmentsThe following environments have been tested for deployment on edge devices:* Java 8, including Raspberry Pi B and Pi2 B* Java 7* Android### Edge devices and back-end systemsYou can send data from an Apache Edgent application to your back-end system when you need to perform analysis that cannot be performed on the edge device, such as:* Running a complex analytic algorithm that requires more resources, such as CPU or memory, than are available on the edge device* Maintaining large amounts of state information about a device, such as several hours worth of state information for a patientâs medical device* Correlating data from the device with data from other sources, such as: - Weather data - Social media data - Data of record, such as a patientâs medical history or trucking manifests - Data from other devicesEdgent communicates with your back-end systems through the following message hubs:* MQTT â The messaging standard for IoT* IBM Watson IoT Platform â A cloud-based service that provides a device model on top of MQTT* Apache Kafka â An enterprise-level message bus* Custom message hubsYour back-end systems can also use analytics to interact with and control edge devices. For example:* A traffic alert system can send an alert to vehicles that are heading towards an area where an accident occurred* A vehicle monitoring system can reduce the maximum engine revs to reduce the chance of failure before the next scheduled service if it detects patterns that indicate a potential problem" }, @@ -138,6 +164,32 @@ { +"title": "Getting started with Apache Edgent pre-1.2.0", +"tags": "", +"keywords": "", +"url": "../docs/old-edgent-getting-started", +"summary": "", +"body": "This information applies to Edgent releases prior to 1.2.0. See [Getting Started](edgent-getting-started) for current releases.## What is Apache Edgent?Edgent is an open source programming model and runtime for edge devices that enables you to analyze streaming data on your edge devices. When you analyze on the edge, you can:* Reduce the amount of data that you transmit to your analytics server* Reduce the amount of data that you storeFor more information, see the [Edgent overview](home).### Apache Edgent and streaming analyticsThe fundamental building block of an Edgent application is a **stream**: a continuous sequence of tuples (messages, events, sensor readings, and so on).The Edgent API provides the ability to process or analyze each tuple as it appears on a stream, resulting in a derived stream.Source streams are streams that originate data for analysis, such as readings from a device's temperature sensor.Streams are terminated using sink functions that can perform l ocal device control or send information to centralized analytic systems through a message hub.Edgent's primary API is functional where streams are sourced, transformed, analyzed or sinked though functions, typically represented as lambda expressions, such as `reading -> reading 80` to filter temperature readings in Fahrenheit.### SamplesSee [samples](old-samples) for information about samples that come with Edgent.### Downloading Apache EdgentTo use Edgent, you need the Edgent JAR files, which you may obtain by completing the following steps.1. Locate the Edgent release you would like to use on the [downloads page]({{ site.data.project.download }})2. In the Bundles column for the desired release: * Click on the _Binary_ link if you simply want to use Edgent. This is the easiest method is to get up and running as it contains a pre-built version of Edgent. * Click on the _Source_ link if you would like access to the Edgent source files. If you choose this method, you must manua lly build Edgent yourself.3. Download the .tgz file from one of the mirror sites4. Unpack the downloaded file: `tar zxvf apache-edgent-X.X.X-incubating-XXX.tgz`5. Obtain the JARs * If you are using a binary bundle, then the Java 8 JARs are located in `edgent-X.X.X/java8` * If you are using a source bundle, build the source code: 1. Install [Gradle](https://gradle.org/) if it is not yet installed 2. Navigate to the unpacked directory: `cd edgent-X.X.X-src` 3. Run `gradle` to initialize the Gradle wrapper 4. Build the code and Javadoc: `./gradlew assemble` 5. The Java 8 JARs are located in `edgent-X.X.X-src/build/distributions/java8`### Setting up your environmentEnsure that you are running a supported environment. For more information, see the [Edgent overview](home). This guide assumes you're running Java 8. The Edgent Java 8 JAR files are located in either the `edgent-X.X.X/java8` or `edgent-X.X.X-src/build/distributions/java8` directory, de pending on whether you downloaded a binary or source bundle.1. Create a new Java project in Eclipse, and specify Java 8 as the execution environment JRE: 2. Include one or more Edgent JARs in your project's build path depending on what features your application uses: 1. Include one or more of the topology providers: * `java8/lib/edgent.providers.development.jar` (if using the [DevelopmentProvider]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/development/DevelopmentProvider.html)) * `java8/lib/edgent.providers.direct.jar`(if using the [DirectProvider]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html)) * `java8/lib/edgent.providers.iot.jar` (if using the [IotProvider]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/iot/IotProvider.html)) 2. Include the JARs for any Edgent connectors or analytic features you use in `java8/connectors` and `java8/analyt ics`, respectively 3. Include the JARs for any Edgent utility features you use: * `java8/utils/metrics/lib/edgent.utils.metrics.jar` (for the [org.apache.edgent.metrics]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/metrics/package-summary.html) package) * `java8/utils/streamscope/lib/edgent.utils.streamscope.jar` (for the [org.apache.edgent.streamscope]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/streamscope/package-summary.html) package) 4. Include the JAR for the [java.util.logging](https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html) framework for [SLF4J](https://www.slf4j.org/): `java8/ext/slf4j-jdk14-X.X.X.jar` Your environment is set up! You can start writing your first Edgent application.## Creating a simple applicationIf you're new to Edgent or to writing streaming applications, the best way to get started is to write a simple program.Edgent is a framework that pushes data analytics an d machine learning to *edge devices*. (Edge devices include things like routers, gateways, machines, equipment, sensors, appliances, or vehicles that are connected to a network.) Edgent enables you to process data locally—such as, in a car engine, on an Android phone, or on a Raspberry Pi—before you send data over a network.For example, if your device takes temperature readings from a sensor 1,000 times per second, it is more efficient to process the data locally and send only interesting or unexpected results over the network. To simulate this, let's define a (simulated) TempSensor class:```javaimport java.util.Random;import org.apache.edgent.function.Supplier;/** * Every time get() is called, TempSensor generates a temperature reading. */public class TempSensor implements Supplier { double currentTemp = 65.0; Random rand; TempSensor(){ rand = new Random(); } @Override public Double get() { // Change the current temperature some random am ount double newTemp = rand.nextGaussian() + currentTemp; currentTemp = newTemp; return currentTemp; }}```Every time you call `TempSensor.get()`, it returns a new temperature reading. The continuous temperature readings are a stream of data that an Edgent application can process.Our sample Edgent application processes this stream by filtering the data and printing the results. Let's define a TempSensorApplication class for the application:```javaimport java.util.concurrent.TimeUnit;import org.apache.edgent.providers.direct.DirectProvider;import org.apache.edgent.topology.TStream;import org.apache.edgent.topology.Topology;public class TempSensorApplication { public static void main(String[] args) throws Exception { TempSensor sensor = new TempSensor(); DirectProvider dp = new DirectProvider(); Topology topology = dp.newTopology(); TStream tempReadings = topology.poll(sensor, 1, TimeUnit.MILLISECONDS); TStream filteredReadin gs = tempReadings.filter(reading -> reading 80); filteredReadings.print(); dp.submit(topology); }}```To understand how the application processes the stream, let's review each line.### Specifying a providerYour first step when you write an Edgent application is to create a [`DirectProvider`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html):```javaDirectProvider dp = new DirectProvider();```A `Provider` is an object that contains information on how and where your Edgent application will run. A `DirectProvider` is a type of Provider that runs your application directly within the current virtual machine when its [`submit()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/providers/direct/DirectProvider.html#submit-org.apache.{{ site.data.project.unix_name }}.topology.Topology-) method is called.### Creating a topologyAdditionally, a Provider is used to create a [`Topology`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/Topology.html) instance:```javaTopology topology = dp.newTopology();```In Edgent, `Topology` is a container that describes the structure of your application:* Where the streams in the application come from* How the data in the stream is modifiedIn the TempSensorApplication class above, we have exactly one data source: the `TempSensor` object. We define the source stream by calling [`topology.poll()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/Topology.html#poll-org.apache.{{ site.data.project.unix_name }}.function.Supplier-long-java.util.concurrent.TimeUnit-), which takes both a [`Supplier`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/function/Supplier.html) function and a time parameter to indicate how frequently readings should be taken. In our case, we read from the sensor every millisecond:```javaTStream tempReadings = topology.poll(sensor, 1, TimeUni t.MILLISECONDS);```### Defining the `TStream` objectCalling `topology.poll()` to define a source stream creates a `TStream` instance, which represents the series of readings taken from the temperature sensor.A streaming application can run indefinitely, so the [`TStream`]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/TStream.html) might see an arbitrarily large number of readings pass through it. Because a `TStream` represents the flow of your data, it supports a number of operations which allow you to modify your data.### Filtering a `TStream`In our example, we want to filter the stream of temperature readings, and remove any \"uninteresting\" or expected readings—specifically readings which are above 50 degrees and below 80 degrees. To do this, we call the `TStream`'s [`filter`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#filter-org.apache.{{ site.data.project.unix_name }}.function.Predicate-) me thod and pass in a function that returns *true* if the data is interesting and *false* if the data is uninteresting:```javaTStream filteredReadings = tempReadings.filter(reading -> reading 80);```As you can see, the function that is passed to `filter` operates on each tuple individually. Unlike data streaming frameworks like [Apache Spark](https://spark.apache.org/), which operate on a collection of data in batch mode, Edgent achieves low latency processing by manipulating each piece of data as soon as it becomes available. Filtering a `TStream` produces another `TStream` that contains only the filtered tuples; for example, the `filteredReadings` stream.### Printing to outputWhen our application detects interesting data (data outside of the expected parameters), we want to print results. You can do this by calling the [`TStream.print()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#print--) method, which prints using `.toString()` on each t uple that passes through the stream:```javafilteredReadings.print();```Unlike `TStream.filter()`, `TStream.print()` does not produce another `TStream`. This is because `TStream.print()` is a **sink**, which represents the terminus of a stream.In addition to `TStream.print()` there are other sink operations that send tuples to an MQTT server, JDBC connection, file, or Kafka cluster. Additionally, you can define your own sink by invoking [`TStream.sink()`]({{ site.docsurl }}/org/apache/{{ site.data.project.unix_name }}/topology/TStream.html#sink-org.apache.{{ site.data.project.unix_name }}.function.Consumer-) and passing in your own function.### Submitting your applicationNow that your application has been completely declared, the final step is to run your application.`DirectProvider` contains a `submit()` method, which runs your application directly within the current virtual machine:```javadp.submit(topology);```After you run your program, you should see output containing only \"int eresting\" data coming from your sensor:```49.90403231177259647.9783750403908446.5927233630903146.68154455165293447.400819234155236...```As you can see, all temperatures are outside the 50-80 degree range. In terms of a real-world application, this would prevent a device from sending superfluous data over a network, thereby reducing communication costs.## Further examplesThis example demonstrates a small piece of Edgent's functionality. Edgent supports more complicated topologies, such as topologies that require merging and splitting data streams, or perform operations which aggregate the last *N* seconds of data (for example, calculating a moving average).For more complex examples, see:* [Edgent sample programs](old-samples)* [Stream processing concepts](streaming-concepts)* [Common Edgent operations](common-edgent-operations)" + +}, + + + + +{ +"title": "Sample programs", +"tags": "", +"keywords": "", +"url": "../docs/old-samples", +"summary": "", +"body": "This information applies to Edgent releases prior to 1.2.0. See [Getting started guide](edgent-getting-started) for current releases.The [Getting started guide](edgent-getting-started) includes a step-by-step walkthrough of a simple Edgent application.Edgent also includes a number of sample Java applications that demonstrate different ways that you can use and implement Edgent.If you are using a released version of Edgent, the samples are already compiled and ready to use. If you downloaded the source or the Git project, the samples are built when you build Edgent.## ResourcesThe samples are currently available only for Java 8 environments. To use the samples, you'll need the resources in the following subdirectories of the Edgent package.:* The `java8/samples` directory contains the Java code for the samples* The `java8/scripts` directory contains the shell scripts that you need to run the samplesIf you use any of the samples in your own applications, ensure that you inclu de the related Edgent JAR files in your `classpath`.## Recommended samplesIn addition to the sample application in the [Getting started guide](edgent-getting-started), the following samples can help you start developing with Edgent:* **HelloEdgent** - This simple program demonstrates the basic mechanics of declaring and executing a topology* **PeriodicSource** - This simple program demonstrates how to periodically poll a source for data to create a source stream* **SimpleFilterTransform** - This simple program demonstrates a simple analytics pipeline: `source -> filter -> transform -> sink`* **SensorAnalytics** - This more complex program demonstrates multiple facets of an Edgent application, including: * Configuration control * Reading data from a device with multiple sensors * Running common analytic algorithms * Publishing results to MQTT server * Receiving commands * Logging results locally * Conditional stream tracing* **IBM Watson IoT Pla tform** - Samples that demonstrate how to use IBM Watson IoT Platform as the IoT scale message hub between Edgent and back-end analytic systems: * [Sample using the no-registration Quickstart service](quickstart)Additional samples are documented in the [Edgent Overview]({{ site.docsurl }}/overview-summary.html#overview.description) section of the Javadoc." + +}, + + + + +{ "title": "Overview", "tags": "", "keywords": "", @@ -150,6 +202,19 @@ +{ +"title": "The Power of Apache Edgent", +"tags": "", +"keywords": "", +"url": "../docs/power-of-edgent", +"summary": "", +"body": "Edgent is designed to accelerate your development of event driven flow-graphstyle analytic applications running on edge devices. This is achieved byEdgent's combination of API, connectors, basic analytics, utilities, and openness!Let's have some fun with a shallow but broad view into what youcan do in a few of lines of code... an introduction to Edgent's capabilities viaa series of terse code fragments.See the [Getting Started Guide](edgent-getting-started) for a step by step introduction,and information about full samples and recipies.Let's start with a complete application that periodically samples a sensorand publishes its values to an Enterprise IoT Hub in less than 10 lines of code```javapublic class ImpressiveEdgentExample { public static void main(String[] args) { DirectProvider provider = new DirectProvider(); Topology top = provider.newTopology(); IotDevice iotConnector = IotpDevice.quickstart(top, \"edgent-intro-device-2\"); // open https://quickstar t.internetofthings.ibmcloud.com/#/device/edgent-intro-device-2 // ingest -> transform -> publish TStream readings = top.poll(new SimulatedTemperatureSensor(), 1, TimeUnit.SECONDS); TStream events = readings.map(JsonFunctions.valueOfNumber(\"temp\")); iotConnector.events(events, \"readingEvents\", QoS.FIRE_AND_FORGET); provider.submit(top); }}```Ok, that was 11 lines and it omitted the imports, but there are only 7 lines in main()!That leveraged the [IotpDevice]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/iotp/IotpDevice.html)connector to the IBM Watson IoT Platform and the platform's Quickstart feature. The value of its Quickstart feature is no account or device preregistration and the ability to open a browser to see thedata being published. Great to quickly get started.Hopefully that had enough of a wow factor to encourage youto keep reading!### Connectors, Ingest and SinkEdgent Applications need to create streams of data from external entities,termed ingest, and sink streams of data to external entities. There are primitives for those operations and a collection ofconnectors to common external entities,more Connectors contributions are welcome!Connectors are just code that make it easier for an Edgent applicationto integrate with an external entity. They use Edgent ingest primitiveslike (`Topology.poll()`, `Topology.events()`, etc), and `TStream.sink()`like any other Edgent code. A connector may provide `Supplier` and `Consumer` functions, for ingest and sink respectively, that an application can use directly with the Edgent API.OK... fewer words, more code!You've already seen publishing using the `IotpDevice` connector.Want to receive [IotDevice]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/iot/IotDevice.html) device commands? Simple!```java TStream cmds = iotConnector.commands(); cmds.sink(cmd -> System.out.println(\"I should handle received cmd: \ "+cmd)); or TStream xzyCmds = iotConnector.command(\"xyzCmds\");```There's an [IotGateway]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/iot/IotGateway.html) device model too.Don't want no stinkin `IotDevice` model and justwant to pub/sub to an MQTT server? No worries! Use the [MqttStreams]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/mqtt/MqttStreams.html) connector```java //IotDevice iotConnector = IotpDevice.quickstart(top, \"edgent-intro-device-2\"); MqttStreams iotConnector = new MqttStreams(top, \"ssl://myMqttServer:8883\", \"my-device-client-id\"); ... //iotConnector.events(events, \"readingEvents\", QoS.FIRE_AND_FORGET); iotConnector.publish(events, \"readingEvents\", QoS.FIRE_AND_FORGET, false); TStream xyzTopicMsgs = iotConnector.subscribe(\"xyzTopic\");```Want to connect to Kafka? Use the [KafkaProducer]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.u nix_name }}/connectors/kafka/KafkaProducer.html) and [KafkaConsumer]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/kafka/KafkaConsumer.html) connectors with similar ease.There's a [JdbcStreams]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/jdbc/JdbcStreams.html) connector too.Want to sink a `TStream` to rolling text files? Use the [FileStreams]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/file/FileStreams.html) connector.```java new File(\"/tmp/MY-DEMO-FILES\").mkdir(); FileStreams.textFileWriter(events.asString(), () -> \"/tmp/MY-DEMO-FILES/READINGS\"); // tail -f /tmp/MY-DEMO-FILES/.READINGS```Or watch for, ingest and process text files? [Csv]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/csv/Csv.html) can be useful if your input lines of comma separated values```java String watchedDir = \"/some/directory/path \"; List csvFieldNames = ... TStream pathnames = FileStreams.directoryWatcher(top, () -> watchedDir, null); TStream lines = FileStreams.textFileReader(pathnames); TStream parsedLines = lines.map(line -> Csv.toJson(Csv.parseCsv(line), csvFieldNames));```Want to sink to a command's stdin? Use the [CommandStreams]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/connectors/command/CommandStreams.html) connector```java TStream events = ... ProcessBuilder cmd = new ProcessBuilder(\"cat\").redirectOutput(new File(\"/dev/stdout\")); CommandStreams.sink(events.asString(), cmd);```Or ingest a command's stdout/err?```java ProcessBuilder cmd = new ProcessBuilder(\"date\", \"-R\"); TStream> readings = CommandStreams.periodicSource(top, cmd, 1, TimeUnit.SECONDS); TStream events = readings .flatMap(list -> list) .map(JsonFunctions.valueOfString(\"date\")); // also note TStream support for a fluent programming sty le // and use of TStream.flatmap() to transform in input list to // an output list and then add each output list item as a separate // tuple to the output stream```Want to sink to a log via SLF4J or another logging system? Just do it!```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(MyClass.class); readings.sink(reading -> logger.info(\"reading: {}\", reading));```Want to publish to Elasticsearch? See [EDGENT-368](https://issues.apache.org/jira/browse/EDGENT-368) for a full code example.### More on IngestYou've seen how to periodically poll a function to get a some data. That's just one of the methods defined in [Topology]({{ site.docsurl }}/index.html?org/apache/{{ site.data.project.unix_name }}/topology/Topology.html) for ingesting data - for creating source streams.Also note that the tuples (a.k.a. events, data, objects) in a [TStream]({{ site.docsurl }}/index.html?org/apache/{{ sit e.data.project.unix_name }}/topology/TStream.html) can be any type. There's no special Edgent tuple type hierarchy.Want readings from multiple sensors in a single stream tuple?```java SimulatedTemperatureSensor tempSensor = new SimulatedTemperatureSensor(); SimpleSimulatedSensor pressureSensor = new SimpleSimulatedSensor(); TStream events = top.poll( () -> { JsonObject jo = new JsonObject(); jo.addProperty(\"temp\", tempSensor.get()); jo.addProperty(\"pressure\", pressureSensor.get()); return jo; }, 1, TimeUnit.SECONDS);```Want to define a class or use an existing one for a tuple?```java public class SensorReading { double temp; double pressure; public SensorReading(double temp, double pressure) { this.temp = temp; this.pressure = pressure; } } SimulatedTemperatureSensor tempSensor = new SimulatedTemperatureSensor(); SimpleSimulatedSensor pressureSensor = new SimpleS imulatedSensor(); TStream readings = top.poll( () -> new Reading(tempSensor.get(), pressureSensor.get()), 1, TimeUnit.SECONDS);```#### Simulated SensorsEdgent provides some simple simulated sensors that can be helpful to get going.You've already seen `SimulatedTemperatureSensor` and`SimpleSimulatedSensor` - included in the Edgent Samples source release bundle.There are additional ones in the same Java package.#### Sensor libraryWondering if Edgent has a sensor library? It does notbec
<TRUNCATED>