Added Key class
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9ceb2d2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+S4-Piper Design
+===============
+
+- Eliminate string identifiers completely and make it work nicely with Guice.
+- Use dependency injection, no more "new".
+- Limit property files to simple parameters. Config file should not be
+a programming language.
+- Configure the app in a GuiceModule.
+- Make fields final private whenever possible and use constructors
+instead of setter methods.
+- Make PEs as immutable as possible.
+- Hide details about partitioning from app developer. The idea is to
+create a graph for the prototypes and have the base classes deal with
+the distributed processing details.
+- Use osgi to create s4 app bundles that can be dropped in a directory
+and get loaded by s4.
+
+I think this can be pretty simple and clean. This is just a first
+pass, we need to brainstorm and have a few iterations.
+
+https://github.com/leoneu/s4-piper
+
+
+- no prototype if possible - all pe instances the same.
+- do we need Stream?
+- how do we configure keys
+
+The event/key is a atomic unit
+
+A PE can listen to many event/keys
+
+for a given PE inst. the set of key values of incoming events have to be the same. (pe inst is keyed on the value)
+
+For each pe inst. each event type has to be mapped to a processing method
+
+currently maps to method signature (which takes event as param) we are happy with this approach.
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..156a949
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License. See accompanying LICENSE file.
+ */
+
+/* Include handy Gradle plugins. */
+apply plugin: 'eclipse'
+apply plugin: 'java'
+apply plugin: "application"
+
+/* Main application to run ... */
+mainClassName = "io.s4.Main"
+
+/* Set a version number for your app. */
+ version = new Version(major: 0, minor: 1, releaseType: 'SNAPSHOT')
+ group = 'io.s4'
+
+ /* All project libraries must be defined here. */
+ libraries = [
+ json: 'org.json:json:20090211',
+ gson: 'com.google.code.gson:gson:1.6',
+ guice: 'com.google.inject:guice:3.0',
+ guice_grapher: 'com.google.inject:guice-grapher:3.0',
+ log4j: 'log4j:log4j:1.2.15',
+ flexjson: 'net.sf.flexjson:flexjson:2.1',
+ bcel: 'org.apache.bcel:bcel:5.2',
+ jakarta_regexp: 'jakarta-regexp:jakarta-regexp:1.4',
+ kryo: 'com.esotericsoftware:kryo:1.01',
+ reflectasm: 'com.esotericsoftware:reflectasm:0.8',
+ minlog: 'com.esotericsoftware:minlog:1.2',
+ asm: 'asm:asm:3.2',
+ commons_logging: 'commons-logging:commons-logging:1.1.1',
+ commons_io: 'commons-io:commons-io:2.0.1',
+ commons_config: 'commons-configuration:commons-configuration:1.6',
+ commons_codec: 'commons-codec:commons-codec:1.4',
+ commons_httpclient: 'commons-httpclient:commons-httpclient:3.1',
+ junit: 'junit:junit:4.4'
+ ]
+
+/* Set Java version. */
+sourceCompatibility = 1.6
+targetCompatibility = 1.6
+
+/* Search these repos to find artifacts. Gradle will download and cache. */
+repositories {
+ mavenLocal()
+ mavenCentral()
+ mavenRepo name: "gson", urls: "http://google-gson.googlecode.com/svn/mavenrepo"
+
+ /* Add lib dir as a repo. Some jar files that are not available
+ in a public repo are distributed in the lib dir. */
+ flatDir name: 'libDir', dirs: "$rootDir/lib"
+}
+
+/* Dependencies. */
+dependencies {
+ compile( libraries.guice )
+ compile( libraries.json)
+ compile( libraries.gson)
+ compile( libraries.log4j )
+ compile( libraries.commons_logging )
+ compile( libraries.commons_io )
+ compile( libraries.commons_config )
+ compile( libraries.commons_codec )
+ compile( libraries.commons_httpclient )
+ testCompile( libraries.junit )
+}
+
+/* Customize your jar files. */
+manifest.mainAttributes(
+ provider: 'gradle',
+ 'Implementation-Url': 'http://s4.io',
+ 'Implementation-Version': version,
+ 'Implementation-Vendor': 'The S4 Project',
+ 'Implementation-Vendor-Id': 'io.s4'
+)
+
+/* Bug workaround. */
+eclipseClasspath {
+ downloadSources = false; // required for eclipseClasspath to work
+}
+
+/* Generates the gradlew scripts.
+http://www.gradle.org/1.0-milestone-3/docs/userguide/gradle_wrapper.html */
+task wrapper(type: Wrapper) {
+ gradleVersion = '1.0-milestone-3'
+}
+
+class Version {
+ int major
+ int minor
+ int bugfix
+ String releaseType
+
+ String toString() {
+ "$major.$minor-$releaseType${bugfix ?: ''}"
+ }
+}
diff --git a/src/main/java/io/s4/Key.java b/src/main/java/io/s4/Key.java
new file mode 100644
index 0000000..c23757a
--- /dev/null
+++ b/src/main/java/io/s4/Key.java
@@ -0,0 +1,28 @@
+package io.s4;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+
+public class Key {
+
+ final private Event event;
+ final private KeyFinder finder;
+ final private String separator;
+
+ public Key(Event event, KeyFinder finder, String separator) {
+ this.event = event;
+ this.finder = finder;
+ this.separator = separator;
+ }
+
+ public List<String> getList() {
+ return finder.get(event);
+ }
+
+ public String get() {
+ List<String> keys = getList();
+
+ return StringUtils.join(keys, separator);
+ }
+}
diff --git a/src/main/java/io/s4/KeyFinder.java b/src/main/java/io/s4/KeyFinder.java
new file mode 100644
index 0000000..43d03ee
--- /dev/null
+++ b/src/main/java/io/s4/KeyFinder.java
@@ -0,0 +1,8 @@
+package io.s4;
+
+import java.util.List;
+
+public interface KeyFinder {
+
+ List<String> get(Event event);
+}
diff --git a/src/main/java/io/s4/MyApp.java b/src/main/java/io/s4/MyApp.java
index bf5d54f..96e352e 100644
--- a/src/main/java/io/s4/MyApp.java
+++ b/src/main/java/io/s4/MyApp.java
@@ -6,21 +6,23 @@
final private Stream s2;
final private ProcessingElement pe1;
final private ProcessingElement pe2;
+ final private Key key;
public MyApp(Stream s1, Stream s2, ProcessingElement pe1,
- ProcessingElement pe2) {
+ ProcessingElement pe2, Key key) {
super();
this.s1 = s1;
this.s2 = s2;
this.pe1 = pe1;
this.pe2 = pe2;
+ this.key = key;
}
@Override
protected void create() {
pe1.setOutput(s1);
- pe2.setInput(s1);
+ pe2.setInput(s1, key);
pe2.setOutput(s2);
}
diff --git a/src/main/java/io/s4/ProcessingElement.java b/src/main/java/io/s4/ProcessingElement.java
index 12b8bba..2e70333 100644
--- a/src/main/java/io/s4/ProcessingElement.java
+++ b/src/main/java/io/s4/ProcessingElement.java
@@ -2,12 +2,15 @@
import java.util.List;
+import com.google.inject.Inject;
+
public abstract class ProcessingElement {
final private App app;
private List<Stream> inputStreams;
private List<Stream> outputStreams;
+ @Inject
public ProcessingElement(App app) {
this.app = app;
@@ -15,7 +18,7 @@
}
- public ProcessingElement setInput(Stream stream) {
+ public ProcessingElement setInput(Stream stream, Key key) {
inputStreams.add(stream);
@@ -38,10 +41,20 @@
}
- abstract public void processInputEvent(Event event);
+ public void processInputEvent(Event event) {
+
+ // map event event_type to processInputEvent(EVENT_TYPE)
+
+ // the method gets auto-generated
+ }
abstract public void sendOutputEvent();
abstract public void init();
+
+ // TODO: Change equals and hashCode in ProcessingElement and
+ // Stream so we can use sets as collection and make sure there are no duplicate prototypes.
+ // Great article: http://www.artima.com/lejava/articles/equality.html
+
}