diff --git a/docker-compose-javaworker.yml b/docker-compose-javaworker.yml new file mode 100644 index 0000000..e60e0bb --- /dev/null +++ b/docker-compose-javaworker.yml @@ -0,0 +1,52 @@ +version: "2" + +services: + vote: + build: ./vote + command: python app.py + volumes: + - ./vote:/app + ports: + - "5000:80" + networks: + - front-tier + - back-tier + + result: + build: ./result + command: nodemon --debug server.js + volumes: + - ./result:/app + ports: + - "5001:80" + - "5858:5858" + networks: + - front-tier + - back-tier + + worker: + build: ./worker/Dockerfile.j + networks: + - back-tier + + redis: + image: redis:alpine + container_name: redis + ports: ["6379"] + networks: + - back-tier + + db: + image: postgres:9.4 + container_name: db + volumes: + - "db-data:/var/lib/postgresql/data" + networks: + - back-tier + +volumes: + db-data: + +networks: + front-tier: + back-tier: \ No newline at end of file diff --git a/worker/Dockerfile b/worker/Dockerfile index 4605cb4..f64167c 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -1,11 +1,11 @@ FROM microsoft/dotnet:1.0.0-preview2-sdk -WORKDIR /app +WORKDIR /code -ADD src/ /app/src/ +ADD src/Worker /code/src/Worker RUN dotnet restore -v minimal src/ \ && dotnet publish -c Release -o ./ src/Worker/ \ && rm -rf src/ $HOME/.nuget/ -CMD dotnet Worker.dll +CMD dotnet Worker.dll \ No newline at end of file diff --git a/worker/Dockerfile.j b/worker/Dockerfile.j new file mode 100644 index 0000000..f90fcba --- /dev/null +++ b/worker/Dockerfile.j @@ -0,0 +1,19 @@ +FROM java:openjdk-8-jdk-alpine + +RUN MAVEN_VERSION=3.3.3 \ + && cd /usr/share \ + && wget http://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz -O - | tar xzf - \ + && mv /usr/share/apache-maven-$MAVEN_VERSION /usr/share/maven \ + && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn + +WORKDIR /code + +ADD pom.xml /code/pom.xml +RUN ["mvn", "dependency:resolve"] +RUN ["mvn", "verify"] + +# Adding source, compile and package into a fat jar +ADD src/main /code/src/main +RUN ["mvn", "package"] + +CMD ["java", "-jar", "target/worker-jar-with-dependencies.jar"] diff --git a/worker/pom.xml b/worker/pom.xml new file mode 100644 index 0000000..1fea098 --- /dev/null +++ b/worker/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + worker + worker + 1.0-SNAPSHOT + + + + + org.json + json + 20140107 + + + + redis.clients + jedis + 2.7.2 + jar + compile + + + + org.postgresql + postgresql + 9.4-1200-jdbc41 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + worker + + + true + worker.Worker + dependency-jars/ + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + attached + + package + + worker + + jar-with-dependencies + + + + worker.Worker + + + + + + + + + diff --git a/worker/src/main/java/worker/Worker.java b/worker/src/main/java/worker/Worker.java new file mode 100644 index 0000000..040c1a2 --- /dev/null +++ b/worker/src/main/java/worker/Worker.java @@ -0,0 +1,102 @@ +package worker; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.exceptions.JedisConnectionException; +import java.sql.*; +import org.json.JSONObject; + +class Worker { + public static void main(String[] args) { + try { + Jedis redis = connectToRedis("redis"); + Connection dbConn = connectToDB("db"); + + System.err.println("Watching vote queue"); + + while (true) { + String voteJSON = redis.blpop(0, "votes").get(1); + JSONObject voteData = new JSONObject(voteJSON); + String voterID = voteData.getString("voter_id"); + String vote = voteData.getString("vote"); + + System.err.printf("Processing vote for '%s' by '%s'\n", vote, voterID); + updateVote(dbConn, voterID, vote); + } + } catch (SQLException e) { + e.printStackTrace(); + System.exit(1); + } + } + + static void updateVote(Connection dbConn, String voterID, String vote) throws SQLException { + PreparedStatement insert = dbConn.prepareStatement( + "INSERT INTO votes (id, vote) VALUES (?, ?)"); + insert.setString(1, voterID); + insert.setString(2, vote); + + try { + insert.executeUpdate(); + } catch (SQLException e) { + PreparedStatement update = dbConn.prepareStatement( + "UPDATE votes SET vote = ? WHERE id = ?"); + update.setString(1, vote); + update.setString(2, voterID); + update.executeUpdate(); + } + } + + static Jedis connectToRedis(String host) { + Jedis conn = new Jedis(host); + + while (true) { + try { + conn.keys("*"); + break; + } catch (JedisConnectionException e) { + System.err.println("Waiting for redis"); + sleep(1000); + } + } + + System.err.println("Connected to redis"); + return conn; + } + + static Connection connectToDB(String host) throws SQLException { + Connection conn = null; + + try { + + Class.forName("org.postgresql.Driver"); + String url = "jdbc:postgresql://" + host + "/postgres"; + + while (conn == null) { + try { + conn = DriverManager.getConnection(url, "postgres", ""); + } catch (SQLException e) { + System.err.println("Waiting for db"); + sleep(1000); + } + } + + PreparedStatement st = conn.prepareStatement( + "CREATE TABLE IF NOT EXISTS votes (id VARCHAR(255) NOT NULL UNIQUE, vote VARCHAR(255) NOT NULL)"); + st.executeUpdate(); + + } catch (ClassNotFoundException e) { + e.printStackTrace(); + System.exit(1); + } + + System.err.println("Connected to db"); + return conn; + } + + static void sleep(long duration) { + try { + Thread.sleep(duration); + } catch (InterruptedException e) { + System.exit(1); + } + } +}