Pārlūkot izejas kodu

Clean up worker service (#272)

* Remove Java project from worker

* Update .NET Core and remove old dotnet codebase from worker service

* Remove Windows-based Compose files and info from README

* Update .NET to 7.0
Michael Irwin 2 gadi atpakaļ
vecāks
revīzija
7e7445a601
34 mainītis faili ar 48 papildinājumiem un 948 dzēšanām
  1. 2 22
      README.md
  2. 0 57
      docker-compose-javaworker.yml
  3. 0 48
      docker-compose-windows-1809.yml
  4. 0 45
      docker-compose-windows.yml
  5. 0 49
      docker-stack-windows-1809.yml
  6. 0 61
      docker-stack-windows.yml
  7. 0 44
      worker/.classpath
  8. 0 23
      worker/.project
  9. 0 2
      worker/.settings/org.eclipse.jdt.apt.core.prefs
  10. 0 7
      worker/.settings/org.eclipse.jdt.core.prefs
  11. 0 4
      worker/.settings/org.eclipse.m2e.core.prefs
  12. 27 11
      worker/Dockerfile
  13. 0 17
      worker/Dockerfile.j
  14. 5 3
      worker/Program.cs
  15. 14 0
      worker/Worker.csproj
  16. 0 16
      worker/dotnet/Dockerfile
  17. 0 16
      worker/dotnet/Dockerfile.1809
  18. 0 7
      worker/dotnet/Worker/Data/IVoteData.cs
  19. 0 35
      worker/dotnet/Worker/Data/MySqlVoteData.cs
  20. 0 16
      worker/dotnet/Worker/Entities/Vote.cs
  21. 0 19
      worker/dotnet/Worker/Entities/VoteContext.cs
  22. 0 12
      worker/dotnet/Worker/Messaging/IMessageQueue.cs
  23. 0 23
      worker/dotnet/Worker/Messaging/MessageHelper.cs
  24. 0 35
      worker/dotnet/Worker/Messaging/MessageQueue.cs
  25. 0 15
      worker/dotnet/Worker/Messaging/Messages/Events/VoteCastEvent.cs
  26. 0 16
      worker/dotnet/Worker/Messaging/Messages/Message.cs
  27. 0 39
      worker/dotnet/Worker/Program.cs
  28. 0 30
      worker/dotnet/Worker/Worker.csproj
  29. 0 62
      worker/dotnet/Worker/Workers/QueueWorker.cs
  30. 0 14
      worker/dotnet/Worker/appsettings.json
  31. 0 84
      worker/pom.xml
  32. 0 14
      worker/src/Worker/Worker.csproj
  33. 0 102
      worker/src/main/java/worker/Worker.java
  34. BIN
      worker/target/classes/worker/Worker.class

+ 2 - 22
README.md

@@ -11,7 +11,7 @@ Download [Docker Desktop](https://www.docker.com/products/docker-desktop) for Ma
 
 ## Linux Containers
 
-The Linux stack uses Python, Node.js, .NET Core (or optionally Java), with Redis for messaging and Postgres for storage.
+The Linux stack uses Python, Node.js, .NET Core, with Redis for messaging and Postgres for storage.
 
 > If you're using [Docker Desktop on Windows](https://store.docker.com/editions/community/docker-ce-desktop-windows), you can run the Linux version by [switching to Linux containers](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers), or run the Windows containers version.
 
@@ -30,26 +30,6 @@ Once you have your swarm, in this directory run:
 docker stack deploy --compose-file docker-stack.yml vote
 ```
 
-## Windows Containers
-
-An alternative version of the app uses Windows containers based on Nano Server. This stack runs on .NET Core, using [NATS](https://nats.io) for messaging and [TiDB](https://github.com/pingcap/tidb) for storage.
-
-You can build from source using:
-
-```
-docker compose -f docker-compose-windows.yml build
-```
-
-Then run the app using:
-
-```
-docker compose -f docker-compose-windows.yml up -d
-```
-
-> Or in a Windows swarm, run `docker stack deploy -c docker-stack-windows.yml vote`
-
-The app will be running at [http://localhost:5000](http://localhost:5000), and the results will be at [http://localhost:5001](http://localhost:5001).
-
 
 Run the app in Kubernetes
 -------------------------
@@ -85,7 +65,7 @@ Architecture
 
 * A front-end web app in [Python](/vote) or [ASP.NET Core](/vote/dotnet) which lets you vote between two options
 * A [Redis](https://hub.docker.com/_/redis/) or [NATS](https://hub.docker.com/_/nats/) queue which collects new votes
-* A [.NET Core](/worker/src/Worker), [Java](/worker/src/main) or [.NET Core 2.1](/worker/dotnet) worker which consumes votes and stores them in…
+* A [.NET Core](/worker/) worker which consumes votes and stores them in…
 * A [Postgres](https://hub.docker.com/_/postgres/) or [TiDB](https://hub.docker.com/r/dockersamples/tidb/tags/) database backed by a Docker volume
 * A [Node.js](/result) or [ASP.NET Core SignalR](/result/dotnet) webapp which shows the results of the voting in real time
 

+ 0 - 57
docker-compose-javaworker.yml

@@ -1,57 +0,0 @@
-version: "3"
-
-services:
-  vote:
-    build: ./vote
-    command: python app.py
-    volumes:
-     - ./vote:/app
-    ports:
-      - "5000:80"
-    networks:
-      - front-tier
-      - back-tier
-
-  result:
-    build: ./result
-    command: nodemon server.js
-    volumes:
-      - ./result:/app
-    ports:
-      - "5001:80"
-      - "5858:5858"
-    networks:
-      - front-tier
-      - back-tier
-
-  worker:
-    build:
-      context: ./worker
-      dockerfile: 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
-    environment:
-      POSTGRES_USER: "postgres"
-      POSTGRES_PASSWORD: "postgres"
-    volumes:
-      - "db-data:/var/lib/postgresql/data"
-    networks:
-      - back-tier
-
-volumes:
-  db-data:
-
-networks:
-  front-tier:
-  back-tier:

+ 0 - 48
docker-compose-windows-1809.yml

@@ -1,48 +0,0 @@
-version: "3.2"
-
-services:
-  vote:
-    image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-1809
-    build:
-      context: ./vote/dotnet
-      dockerfile: Dockerfile.1809
-    ports:
-      - "5000:80"
-    depends_on:
-      - message-queue
-
-  result:
-    image: dockersamples/examplevotingapp_result:dotnet-nanoserver-1809
-    build:
-      context: ./result/dotnet
-      dockerfile: Dockerfile.1809
-    ports:
-      - "5001:80"
-    environment:
-      - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    depends_on:
-      - db
-
-  worker:
-    image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-1809
-    build:
-      context: ./worker/dotnet
-      dockerfile: Dockerfile.1809
-    environment:
-      - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    depends_on:
-      - message-queue
-      - db
-
-  message-queue:
-    image: nats:2.0.4
-
-  db:
-    image: dockersamples/tidb:nanoserver-1809
-    ports:
-      - "3306:4000"
-
-networks:
-  default:
-    external:
-      name: nat

+ 0 - 45
docker-compose-windows.yml

@@ -1,45 +0,0 @@
-version: "3.2"
-
-services:
-  vote:
-    image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-sac2016
-    build: 
-      context: ./vote/dotnet
-    ports:
-      - "5000:80"
-    depends_on:
-      - message-queue
-
-  result:
-    image: dockersamples/examplevotingapp_result:dotnet-nanoserver-sac2016
-    build: 
-      context: ./result/dotnet
-    ports:
-      - "5001:80"
-    environment:      
-      - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    depends_on:
-      - db
-
-  worker:
-    image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-sac2016
-    build:
-      context: ./worker/dotnet
-    environment:      
-      - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    depends_on:
-      - message-queue
-      - db
-
-  message-queue:
-    image: nats:nanoserver
-
-  db:
-    image: dockersamples/tidb:nanoserver    
-    ports:
-      - "3306:4000"
-
-networks:
-  default:
-    external:
-      name: nat

+ 0 - 49
docker-stack-windows-1809.yml

@@ -1,49 +0,0 @@
-version: "3.2"
-
-services:
-  vote:
-    image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-1809
-    ports:
-      - "5000:80"
-    deploy:
-      mode: replicated
-      replicas: 4
-    networks:
-      - frontend
-      - backend
-
-  result:
-    image: dockersamples/examplevotingapp_result:dotnet-nanoserver-1809
-    environment:      
-      - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    ports:
-      - "5001:80"
-    networks:
-      - frontend
-      - backend
-
-  worker:
-    image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-1809
-    environment:      
-      - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    deploy:
-      mode: replicated
-      replicas: 3
-    networks:
-      - backend
-
-  message-queue:
-    image: dockersamples/nats:nanoserver-1809
-    networks:
-      - backend
-
-  db:
-    image: dockersamples/tidb:nanoserver-1809
-    ports:
-      - "3306:4000"
-    networks:
-      - backend
-
-networks:
-  frontend:
-  backend:

+ 0 - 61
docker-stack-windows.yml

@@ -1,61 +0,0 @@
-version: "3.2"
-
-services:
-  vote:
-    image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-sac2016
-    ports:
-      - mode: host
-        target: 80
-        published: 5000
-    deploy:
-      endpoint_mode: dnsrr
-    networks:
-      - frontend
-      - backend
-
-  result:
-    image: dockersamples/examplevotingapp_result:dotnet-nanoserver-sac2016
-    environment:      
-      - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    ports:
-      - mode: host
-        target: 80
-        published: 5001
-    deploy:
-      endpoint_mode: dnsrr
-    networks:
-      - frontend
-      - backend
-
-  worker:
-    image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-sac2016
-    environment:      
-      - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
-    deploy:
-      endpoint_mode: dnsrr
-      mode: replicated
-      replicas: 3
-    networks:
-      - backend
-
-  message-queue:
-    image: nats:nanoserver
-    deploy:
-      endpoint_mode: dnsrr
-    networks:
-      - backend
-
-  db:
-    image: dockersamples/tidb:nanoserver
-    ports:
-      - mode: host
-        target: 4000
-        published: 3306
-    deploy:
-      endpoint_mode: dnsrr
-    networks:
-      - backend
-
-networks:
-  frontend:
-  backend:

+ 0 - 44
worker/.classpath

@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" output="target/classes" path="src/main/java">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="test" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
-		<attributes>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
-		<attributes>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" path="target/generated-sources/annotations">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="ignore_optional_problems" value="true"/>
-			<attribute name="m2e-apt" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="ignore_optional_problems" value="true"/>
-			<attribute name="m2e-apt" value="true"/>
-			<attribute name="test" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="output" path="target/classes"/>
-</classpath>

+ 0 - 23
worker/.project

@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>worker</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.m2e.core.maven2Builder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.m2e.core.maven2Nature</nature>
-	</natures>
-</projectDescription>

+ 0 - 2
worker/.settings/org.eclipse.jdt.apt.core.prefs

@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.apt.aptEnabled=false

+ 0 - 7
worker/.settings/org.eclipse.jdt.core.prefs

@@ -1,7 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.processAnnotations=disabled
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.7

+ 0 - 4
worker/.settings/org.eclipse.m2e.core.prefs

@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1

+ 27 - 11
worker/Dockerfile

@@ -1,16 +1,32 @@
-FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder
+# because of dotnet, we always build on amd64, and target platforms in cli
+# dotnet doesn't support QEMU for building or running. 
+# (errors common in arm/v7 32bit) https://github.com/dotnet/dotnet-docker/issues/1537
+# https://hub.docker.com/_/microsoft-dotnet
+# hadolint ignore=DL3029
+FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/dotnet/sdk:7.0 as build
+ARG TARGETPLATFORM
+ARG BUILDPLATFORM
+RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM"
 
-WORKDIR /Worker
-COPY src/Worker/Worker.csproj .
-RUN dotnet restore
+WORKDIR /source
+COPY *.csproj .
+RUN case ${TARGETPLATFORM} in \
+         "linux/amd64")  ARCH=x64  ;; \
+         "linux/arm64")  ARCH=arm64  ;; \
+         "linux/arm/v7") ARCH=arm  ;; \
+    esac \
+    && dotnet restore -r linux-${ARCH}
 
-COPY src/Worker/ .
-RUN dotnet publish -c Release -o /out Worker.csproj
+COPY . .
+RUN  case ${TARGETPLATFORM} in \
+         "linux/amd64")  ARCH=x64  ;; \
+         "linux/arm64")  ARCH=arm64  ;; \
+         "linux/arm/v7") ARCH=arm  ;; \
+    esac \
+    && dotnet publish -c release -o /app -r linux-${ARCH} --self-contained false --no-restore
 
 # app image
-FROM mcr.microsoft.com/dotnet/core/runtime:3.1
-
+FROM mcr.microsoft.com/dotnet/runtime:7.0
 WORKDIR /app
-ENTRYPOINT ["dotnet", "Worker.dll"]
-
-COPY --from=builder /out .
+COPY --from=build /app .
+ENTRYPOINT ["dotnet", "Worker.dll"]

+ 0 - 17
worker/Dockerfile.j

@@ -1,17 +0,0 @@
-FROM maven:3.5-jdk-8-alpine AS build
-
-WORKDIR /code
-
-COPY pom.xml /code/pom.xml
-RUN ["mvn", "dependency:resolve"]
-RUN ["mvn", "verify"]
-
-# Adding source, compile and package into a fat jar
-COPY ["src/main", "/code/src/main"]
-RUN ["mvn", "package"]
-
-FROM openjdk:8-jre-alpine
-
-COPY --from=build /code/target/worker-jar-with-dependencies.jar /
-
-CMD ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-jar", "/worker-jar-with-dependencies.jar"]

+ 5 - 3
worker/src/Worker/Program.cs → worker/Program.cs

@@ -48,8 +48,10 @@ namespace Worker
                             Console.WriteLine("Reconnecting DB");
                             pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;");
                         }
-                        // Normal +1 vote requested
-                        UpdateVote(pgsql, vote.voter_id, vote.vote);
+                        else
+                        { // Normal +1 vote requested
+                            UpdateVote(pgsql, vote.voter_id, vote.vote);
+                        }
                     }
                     else
                     {
@@ -149,4 +151,4 @@ namespace Worker
             }
         }
     }
-}
+}

+ 14 - 0
worker/Worker.csproj

@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net7.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="StackExchange.Redis" Version="2.2.4" />
+    <PackageReference Include="Npgsql" Version="4.1.9" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+  </ItemGroup>
+
+</Project>

+ 0 - 16
worker/dotnet/Dockerfile

@@ -1,16 +0,0 @@
-FROM microsoft/dotnet:2.1-sdk-nanoserver-sac2016 as builder
-
-WORKDIR /Worker
-COPY Worker/Worker.csproj .
-RUN dotnet restore
-
-COPY /Worker .
-RUN dotnet publish -c Release -o /out Worker.csproj
-
-# app image
-FROM microsoft/dotnet:2.1-runtime-nanoserver-sac2016
-
-WORKDIR /app
-ENTRYPOINT ["dotnet", "Worker.dll"]
-
-COPY --from=builder /out .

+ 0 - 16
worker/dotnet/Dockerfile.1809

@@ -1,16 +0,0 @@
-FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder
-
-WORKDIR /Worker
-COPY Worker/Worker.csproj .
-RUN dotnet restore
-
-COPY /Worker .
-RUN dotnet publish -c Release -o /out Worker.csproj
-
-# app image
-FROM mcr.microsoft.com/dotnet/core/runtime:3.1
-
-WORKDIR /app
-ENTRYPOINT ["dotnet", "Worker.dll"]
-
-COPY --from=builder /out .

+ 0 - 7
worker/dotnet/Worker/Data/IVoteData.cs

@@ -1,7 +0,0 @@
-namespace Worker.Data
-{
-    public interface IVoteData
-    {
-        void Set(string voterId, string vote);
-    }
-}

+ 0 - 35
worker/dotnet/Worker/Data/MySqlVoteData.cs

@@ -1,35 +0,0 @@
-using Microsoft.Extensions.Logging;
-using Worker.Entities;
-
-namespace Worker.Data
-{
-    public class MySqlVoteData : IVoteData
-    {
-        private readonly VoteContext _context;        
-        private readonly ILogger _logger;
-
-        public MySqlVoteData(VoteContext context, ILogger<MySqlVoteData> logger)
-        {
-            _context = context;
-            _logger = logger;            
-        }
-
-        public void Set(string voterId, string vote)
-        {
-            var currentVote = _context.Votes.Find(voterId);
-            if (currentVote == null)
-            {
-                _context.Votes.Add(new Vote
-                {
-                    VoterId = voterId,
-                    VoteOption = vote
-                });
-            }
-            else if (currentVote.VoteOption != vote)
-            {
-                currentVote.VoteOption = vote;
-            }
-            _context.SaveChanges();
-        }
-    }
-}

+ 0 - 16
worker/dotnet/Worker/Entities/Vote.cs

@@ -1,16 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Worker.Entities
-{
-    [Table("votes")]
-    public class Vote
-    {
-        [Column("id")]
-        [Key]
-        public string VoterId { get; set; }
-
-        [Column("vote")]
-        public string VoteOption { get; set; }
-    }
-}

+ 0 - 19
worker/dotnet/Worker/Entities/VoteContext.cs

@@ -1,19 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-
-namespace Worker.Entities
-{
-    public class VoteContext : DbContext
-    {
-        private static bool _EnsureCreated;
-        public VoteContext(DbContextOptions options) : base(options)
-        {
-            if (!_EnsureCreated)
-            {
-                Database.EnsureCreated();
-                _EnsureCreated = true;
-            }
-        }
-
-        public DbSet<Vote> Votes { get; set; }
-    }
-}

+ 0 - 12
worker/dotnet/Worker/Messaging/IMessageQueue.cs

@@ -1,12 +0,0 @@
-using NATS.Client;
-using Worker.Messaging.Messages;
-
-namespace Worker.Messaging
-{
-    public interface IMessageQueue
-    {
-        IConnection CreateConnection();
-
-        void Publish<TMessage>(TMessage message) where TMessage : Message;
-    }
-}

+ 0 - 23
worker/dotnet/Worker/Messaging/MessageHelper.cs

@@ -1,23 +0,0 @@
-using Newtonsoft.Json;
-using Worker.Messaging.Messages;
-using System.Text;
-
-namespace Worker.Messaging
-{
-    public class MessageHelper
-    {
-        public static byte[] ToData<TMessage>(TMessage message)
-            where TMessage : Message
-        {
-            var json = JsonConvert.SerializeObject(message);
-            return Encoding.Unicode.GetBytes(json);
-        }
-
-        public static TMessage FromData<TMessage>(byte[] data)
-            where TMessage : Message
-        {
-            var json = Encoding.Unicode.GetString(data);
-            return (TMessage)JsonConvert.DeserializeObject<TMessage>(json);
-        }
-    }
-}

+ 0 - 35
worker/dotnet/Worker/Messaging/MessageQueue.cs

@@ -1,35 +0,0 @@
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Logging;
-using NATS.Client;
-using Worker.Messaging.Messages;
-
-namespace Worker.Messaging
-{
-    public class MessageQueue : IMessageQueue
-    {
-        protected readonly IConfiguration _configuration;
-        protected readonly ILogger _logger;
-
-        public MessageQueue(IConfiguration configuration, ILogger<MessageQueue> logger)
-        {
-            _configuration = configuration;
-            _logger = logger;
-        }
-
-        public void Publish<TMessage>(TMessage message)
-            where TMessage : Message
-        {
-            using (var connection = CreateConnection())
-            {
-                var data = MessageHelper.ToData(message);
-                connection.Publish(message.Subject, data);
-            }
-        }
-
-        public IConnection CreateConnection()
-        {
-            var url = _configuration.GetValue<string>("MessageQueue:Url");
-            return new ConnectionFactory().CreateConnection(url);
-        }
-    }
-}

+ 0 - 15
worker/dotnet/Worker/Messaging/Messages/Events/VoteCastEvent.cs

@@ -1,15 +0,0 @@
-using System;
-
-namespace Worker.Messaging.Messages
-{
-    public class VoteCastEvent : Message
-    {
-        public override string Subject { get { return MessageSubject; } }
-
-        public string VoterId {get; set;}
-
-        public string Vote {get; set; }
-
-         public static string MessageSubject = "events.vote.votecast";
-    }
-}

+ 0 - 16
worker/dotnet/Worker/Messaging/Messages/Message.cs

@@ -1,16 +0,0 @@
-using System;
-
-namespace Worker.Messaging.Messages
-{
-    public abstract class Message
-    {
-        public string CorrelationId { get; set; }  
-        
-        public abstract string Subject { get; }      
-
-        public Message()
-        {
-            CorrelationId = Guid.NewGuid().ToString();
-        }
-    }
-}

+ 0 - 39
worker/dotnet/Worker/Program.cs

@@ -1,39 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using System;
-using Worker.Data;
-using Worker.Entities;
-using Worker.Messaging;
-using Worker.Workers;
-
-namespace Worker
-{
-    class Program
-    {
-        static void Main(string[] args)
-        {
-            var config = new ConfigurationBuilder()
-                .AddJsonFile("appsettings.json")
-                .AddEnvironmentVariables()
-                .Build();
-
-            var loggerFactory = new LoggerFactory()
-                .AddConsole();
-
-            var services = new ServiceCollection()
-                .AddSingleton(loggerFactory)
-                .AddLogging()
-                .AddSingleton<IConfiguration>(config)
-                .AddTransient<IVoteData, MySqlVoteData>()
-                .AddTransient<IMessageQueue, MessageQueue>()
-                .AddSingleton<QueueWorker>()
-                .AddDbContext<VoteContext>(builder => builder.UseMySQL(config.GetConnectionString("VoteData")));
-
-            var provider = services.BuildServiceProvider();
-            var worker = provider.GetService<QueueWorker>();
-            worker.Start();
-        }
-    }
-}

+ 0 - 30
worker/dotnet/Worker/Worker.csproj

@@ -1,30 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <None Remove="appsettings.json" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Content Include="appsettings.json">
-      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-  </ItemGroup>  
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.3" />
-    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.1" />
-    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
-    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
-    <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
-    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
-    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.12" />
-    <PackageReference Include="NATS.Client" Version="0.8.1" />
-  </ItemGroup>
-
-</Project>

+ 0 - 62
worker/dotnet/Worker/Workers/QueueWorker.cs

@@ -1,62 +0,0 @@
-using System;
-using System.Threading;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Logging;
-using NATS.Client;
-using Worker.Data;
-using Worker.Messaging;
-using Worker.Messaging.Messages;
-
-namespace Worker.Workers
-{
-    public class QueueWorker
-    {
-        private static ManualResetEvent _ResetEvent = new ManualResetEvent(false);
-        private const string QUEUE_GROUP = "save-handler";
-
-        private readonly IMessageQueue _messageQueue;
-        private readonly IConfiguration _config;
-        private readonly IVoteData _data;
-        protected readonly ILogger _logger;
-
-        public QueueWorker(IMessageQueue messageQueue, IVoteData data, IConfiguration config, ILogger<QueueWorker> logger)
-        {
-            _messageQueue = messageQueue;
-            _data = data;
-            _config = config;
-            _logger = logger;
-        }
-
-        public void Start()
-        {       
-            _logger.LogInformation($"Connecting to message queue url: {_config.GetValue<string>("MessageQueue:Url")}");
-            using (var connection = _messageQueue.CreateConnection())
-            {
-                var subscription = connection.SubscribeAsync(VoteCastEvent.MessageSubject, QUEUE_GROUP);
-                subscription.MessageHandler += SaveVote;
-                subscription.Start();
-                _logger.LogInformation($"Listening on subject: {VoteCastEvent.MessageSubject}, queue: {QUEUE_GROUP}");
-
-                _ResetEvent.WaitOne();
-                connection.Close();
-            }
-        }
-
-        private void SaveVote(object sender, MsgHandlerEventArgs e)
-        {
-            _logger.LogDebug($"Received message, subject: {e.Message.Subject}");
-            var voteMessage = MessageHelper.FromData<VoteCastEvent>(e.Message.Data);
-            _logger.LogInformation($"Processing vote for '{voteMessage.Vote}' by '{voteMessage.VoterId}'");
-            try
-            {
-                _data.Set(voteMessage.VoterId, voteMessage.Vote);
-                _logger.LogDebug($"Succesffuly processed vote by '{voteMessage.VoterId}'");
-            }
-            catch (Exception ex)
-            {
-                _logger.LogError($"Vote processing FAILED for '{voteMessage.VoterId}', exception: {ex}");
-            }
-            
-        }
-    }
-}

+ 0 - 14
worker/dotnet/Worker/appsettings.json

@@ -1,14 +0,0 @@
-{
-  "MessageQueue": {
-    "Url": "nats://message-queue:4222"
-  },
-  "ConnectionStrings": {
-    "VoteData": "Server=mysql;Port=4000;Database=votes;User=root;SslMode=None"
-  },
-  "Logging": {
-    "LogLevel": {
-      "Default": "Information"
-    }
-  },
-  "AllowedHosts": "*"
-}

+ 0 - 84
worker/pom.xml

@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>worker</groupId>
-  <artifactId>worker</artifactId>
-  <version>1.0-SNAPSHOT</version>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>org.json</groupId>
-      <artifactId>json</artifactId>
-      <version>20140107</version>
-    </dependency>
-
-    <dependency>
-        <groupId>redis.clients</groupId>
-        <artifactId>jedis</artifactId>
-        <version>2.7.2</version>
-        <type>jar</type>
-        <scope>compile</scope>
-    </dependency>
-
-    <dependency>
-        <groupId>org.postgresql</groupId>
-        <artifactId>postgresql</artifactId>
-        <version>9.4-1200-jdbc41</version>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <version>2.4</version>
-        <configuration>
-          <finalName>worker</finalName>
-          <archive>
-            <manifest>
-              <addClasspath>true</addClasspath>
-              <mainClass>worker.Worker</mainClass>
-              <classpathPrefix>dependency-jars/</classpathPrefix>
-            </manifest>
-          </archive>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.1</version>
-        <configuration>
-          <source>1.7</source>
-          <target>1.7</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>attached</goal>
-            </goals>
-            <phase>package</phase>
-            <configuration>
-              <finalName>worker</finalName>
-              <descriptorRefs>
-                <descriptorRef>jar-with-dependencies</descriptorRef>
-              </descriptorRefs>
-              <archive>
-                <manifest>
-                  <mainClass>worker.Worker</mainClass>
-                </manifest>
-              </archive>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>

+ 0 - 14
worker/src/Worker/Worker.csproj

@@ -1,14 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="StackExchange.Redis" Version="2.0.601" />
-    <PackageReference Include="Npgsql" Version="4.0.9" />
-    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
-  </ItemGroup>
-
-</Project>

+ 0 - 102
worker/src/main/java/worker/Worker.java

@@ -1,102 +0,0 @@
-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", "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);
-    }
-  }
-}

BIN
worker/target/classes/worker/Worker.class