Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 69 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

Have you ever attended a wedding or a birthday party? If yes, you probably saw photo booth there. You get in, take a photo and paste it in the guest book - simple and fun. But what if we could bring this fun into the digital world? This is where **LensUp** comes to the rescue. **LensUp** is a web application that serves as a virtual gallery, allowing party guests to upload their photos from the event and also write down their wishes.

- [Project status](#Project status)
- [100 days roadmap](#100 days roadmap)
- [How to run LensUp locally](#How to run LensUp locally)
- [TODO list (100 days)](#TODO list (100 days))
- [Project status](#project-status)
- [100 days roadmap](#100-days-roadmap)
- [How to run LensUp locally](#how-to-run-lensup-locally)
- [TODO list (100 days)](#todo-list-(100-days))

# Project status
The video shows the project status as of `26.04.2024` and the core functionality of the application.
Expand Down Expand Up @@ -73,26 +73,85 @@ Description:

## How to run LensUp locally

You can run the project locally on your machine using Docker. All services will be hosted on your WLAN network. Follow the steps below to run the application locally.
You can run the project locally on your machine using Docker. Follow the steps below to run the application locally:

1. Before we start you should generate `dev-certs` for LensUp on your machine. This operation is required to hosting ASP.NET Core images with Docker over HTTPS. So generate a certificate and configure the local machine:
1. Before we start you should generate `dev-certs` for **LensUp** on your machine. This operation is required to hosting ASP.NET Core images with Docker over HTTPS. So generate a certificate using these commands:

```bash
dotnet dev-certs https -ep "%USERPROFILE%\.aspnet\https\lens-up.pfx" -p localCertPassword
dotnet dev-certs https --trust
```

**Replace `%USERPROFILE%` with your computer name.** Example `"C:\Users\Kamil\.aspnet\https\lens-up.pfx"`
**Replace `%USERPROFILE%` with your computer name.** Example `"C:\Users\Dell Precision 7520\.aspnet\https\lens-up.pfx"`

**This is necessary step, because docker-compose refers to that certificate**.
**For local development purposes, we will use the password `localCertPassword`. Do not change this, as the same password is used in the `docker-compose.yml` file.**

2. Install `docker desktop` on your machine (skip if you already done it).
The above commands should generate a `lens-up.pfx` certificate, and should place it in the directory as shown in the screenshot below.

![lens-up-cert](/docs/lens-up-cert.png)

**This is necessary step, because docker-compose refers to that certificate!**

2. Install `docker desktop` on your machine *(skip if you already done it)*.

3. Run your `docker desktop` application.

4. To be continued.
4. In the main project directory (`lens-up`), where the `docker-compose.yml` file is located, run the command `docker-compose build`. This will build 7 necessary LensUp images. After completing these steps, you should see new images in the Docker Desktop application.

![lens-up-docker-images](/docs/lens-up-docker-images.png)

5. After the build command, run the `docker-compose up` to start the entire infrastructure. You should see in Docker Desktop that 7 containers related to LensUp have been started.

![lens-up-containers](/docs/lens-up-containers.png)

6. Now the entire application is running on your machine. You can use the following addresses:

- Backend services:

- `LensUp.BackOfficeService.API` swagger - https://localhost:8085/swagger/index.html
- `LensUp.GalleryService.API` swagger - https://localhost:8083/swagger/index.html
- `LensUp.GalleryService.WebhookTriggerSimulator` - http://localhost:8086/
- `LensUp.PhotoCollectorService.API` swagger - https://localhost:8081/swagger/index.html

- UI applications:

- `LensUp.GalleryService.UI` - http://localhost:5001/

- `LensUp.PhotoCollectorService.UI` - http://localhost:5002/

*On LensUp.PhotoCollectorService.UI you will see error page, because you need to navigate to the view associated with a specific gallery, which you haven't created yet.*



**How to create your first gallery and have fun with LensUp?**

1. Go to `LensUp.BackOfficeService.API` - https://localhost:8085/swagger/index.html

2. Use `Create` endpoint to create your gallery. The endpoint returns the gallery identifier after it is created **(1)**.

![lens-up-create-endpoint](/docs/lens-up-create-endpoint.png)

3. Before using the gallery, we need to activate it. In that case use `Activate` endpoint and pass `galleryId` and `endDate` in request body. Remember the `endDate` is validated and must be greater than the current time. Otherwise, your gallery will be treated as expired. The endpoint returns the gallery `enterCode` after it is activated **(1)**.

![lens-up-activate-endpoint](/docs/lens-up-activate-endpoint.png)

4. With your gallery `enterCode` you can open your gallery using `LensUp.GalleryService.UI` - http://localhost:5001/

Log in to your gallery using `enterCode`.

![lens-up-login-form](/docs/lens-up-login-form.png)

5. Now you can scan gallery QR code and upload photos to it. The code redirects to a form for adding photos to the gallery. You can use browser tool to scan QR code or if it doesn't work you can just go to `http://localhost:5002/upload-photo/{enterCode}`.

![lens-up-gallery-qr-code](/docs/lens-up-gallery-qr-code.png)

6. QR Code redirects you to add photo and wishes form. Now you can upload your data to gallery.

![lens-up-gallery-qr-code](/docs/lens-up-upload-photo-form.png)

7. After successfully completing the form, we should see success notification and the photo should appear in the gallery.

![lens-up-upload-flow](/docs/lens-up-upload-flow.gif)

## TODO list (100 days)

Expand Down
5 changes: 0 additions & 5 deletions backend-services/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues" Version="5.2.0" />
<PackageVersion Include="Microsoft.Extensions.Azure" Version="1.7.2" />
<PackageVersion Include="Azure.Data.Tables" Version="12.8.3" />
<PackageVersion Include="Azure.Storage.Queues" Version="12.17.1" />
Expand All @@ -24,9 +23,5 @@
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="Moq" Version="4.20.70" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="1.20.1" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
<PackageVersion Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.1.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"AzureStorage": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://host.docker.internal:10000/devstoreaccount1;QueueEndpoint=http://host.docker.internal:10001/devstoreaccount1;TableEndpoint=http://host.docker.internal:10002/devstoreaccount1;"
},
"ApplicationOptions": {
"PhotoCollectorUIUrl": "http://localhost:5002"
"PhotoCollectorUIUrl": "http://localhost:5002/upload-photo"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace LensUp.GalleryService.WebhookTriggerSimulator;

internal static class AppSettingsKeys
{
public const string AzureWebJobsAzureStorageConnectionString = "AzureWebJobsAzureStorageConnectionString";
public const string WebhookUrl = "WebhookUrl";
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0 AS base
WORKDIR /home/site/wwwroot
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS installer-env

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["Directory.Build.props", "/"]
COPY ["Directory.Packages.props", "/"]
COPY ["StyleCop.ruleset", "/"]
COPY ["photo-collector-service/src/LensUp.PhotoCollectorService.Contracts/LensUp.PhotoCollectorService.Contracts.csproj", "/photo-collector-service/src/LensUp.PhotoCollectorService.Contracts/"]
COPY ["common/src/LensUp.Common.Types/LensUp.Common.Types.csproj", "/common/src/LensUp.Common.Types/"]
COPY ["gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/LensUp.GalleryService.WebhookTriggerSimulator.csproj", "/gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/"]

RUN dotnet restore "gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/LensUp.GalleryService.WebhookTriggerSimulator.csproj"

COPY . /src/func-app

RUN cd /src/func-app && \
mkdir -p /home/site/wwwroot && \
dotnet publish gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/LensUp.GalleryService.WebhookTriggerSimulator.csproj -c Release --output /home/site/wwwroot

FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0
RUN dotnet restore "/gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/LensUp.GalleryService.WebhookTriggerSimulator.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "./gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/LensUp.GalleryService.WebhookTriggerSimulator.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/LensUp.GalleryService.WebhookTriggerSimulator.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /home/site/wwwroot
COPY --from=publish /app/publish .
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true

EXPOSE 8080
EXPOSE 8086

COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@
<Nullable>enable</Nullable>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues" Version="5.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.1.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\src\LensUp.Common.Types\LensUp.Common.Types.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using LensUp.Common.Types.Constants;
using LensUp.PhotoCollectorService.Contracts.Events;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Configuration;
using System.Text;
using System.Text.Json;

Expand All @@ -10,13 +11,13 @@ namespace LensUp.GalleryService.WebhookTriggerSimulator;
// Workaround - simulate webhook trigger
public sealed class WebhookTriggerSimulatorFunction
{
private const string WebhookUrl = "http://localhost:8082/Webhook";
private readonly string WebhookUrl = Environment.GetEnvironmentVariable(AppSettingsKeys.WebhookUrl) ?? throw new ArgumentNullException(AppSettingsKeys.WebhookUrl);
public WebhookTriggerSimulatorFunction()
{
}

[Function(nameof(WebhookTriggerSimulatorFunction))]
public async Task Run([QueueTrigger(QueueNames.PhotoQueue, Connection = "AzureStorageConnectionString")] QueueMessage message)
public async Task Run([QueueTrigger(QueueNames.PhotoQueue, Connection = AppSettingsKeys.AzureWebJobsAzureStorageConnectionString)] QueueMessage message)
{

if (message?.Body == null)
Expand All @@ -37,7 +38,7 @@ public async Task Run([QueueTrigger(QueueNames.PhotoQueue, Connection = "AzureSt
using var client = new HttpClient(clientHandler);

var content = new StringContent(JsonSerializer.Serialize(@event), Encoding.UTF8, "application/json");
await client.PostAsync(WebhookUrl, content);
await client.PostAsync(this.WebhookUrl, content);
}
catch (Exception exception)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
"version": "2.0",
"extensions": {
"queues": {
"maxPollingInterval": "00:00:02",
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
}
}
60 changes: 47 additions & 13 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ services:
depends_on:
- azurite

lensup.photocollectorservice.ui:
build:
context: ./ui-applications
dockerfile: Dockerfile
args:
SERVICE: photo-collector-ui
image: lensup.photocollectorservice.ui
container_name: lensup.photocollectorservice.ui
ports:
- "5002:5002"
environment:
- NODE_ENV=dev
command: npm run dev
depends_on:
- lensup.photocollectorservice.api

lensup.galleryservice.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
Expand All @@ -51,19 +67,37 @@ services:
depends_on:
- azurite

# lensup.galleryservice.webhooktriggersimulator:
# environment:
# - AzureFunctionsJobHost__Http__Port=8086
# container_name: lensup.galleryservice.webhooktriggersimulator
# image: lensup.galleryservice.webhooktriggersimulator
# build:
# context: ./backend-services
# dockerfile: gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/Dockerfile
# ports:
# - "8086:8080"
# depends_on:
# - azurite
# - lensup.galleryservice.api
lensup.galleryservice.webhooktriggersimulator:
environment:
- AzureFunctionsJobHost__Http__Port=8086
- AzureWebJobsAzureStorageConnectionString=DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;QueueEndpoint=http://host.docker.internal:10001/devstoreaccount1;
- WebhookUrl=http://host.docker.internal:8082/Webhook
container_name: lensup.galleryservice.webhooktriggersimulator
image: lensup.galleryservice.webhooktriggersimulator
build:
context: ./backend-services
dockerfile: gallery-service/src/LensUp.GalleryService.WebhookTriggerSimulator/Dockerfile
ports:
- "8086:8080"
depends_on:
- azurite
- lensup.galleryservice.api

lensup.galleryservice.ui:
build:
context: ./ui-applications
dockerfile: Dockerfile
args:
SERVICE: gallery-ui
image: lensup.galleryservice.ui
container_name: lensup.galleryservice.ui
ports:
- "5001:5001"
environment:
- NODE_ENV=dev
command: npm run dev
depends_on:
- lensup.galleryservice.api

lensup.backofficeservice.api:
environment:
Expand Down
Binary file added docs/lens-up-activate-endpoint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-cert.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-containers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-create-endpoint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-docker-images.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-gallery-qr-code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-login-form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-upload-flow.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/lens-up-upload-photo-form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions ui-applications/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM node:alpine as builder
ARG SERVICE
WORKDIR /usr/src/app

COPY --chown=node:node package*.json lerna.json tsconfig.json ./
COPY --chown=node:node packages/shared-components ./packages/shared-components
COPY --chown=node:node packages/${SERVICE} ./packages/${SERVICE}
RUN npm install --loglevel notice --unsafe-perm

ENV SERVICE_NAME=${SERVICE}

EXPOSE 5000
CMD ["npm", "--prefix", "services/${SERVICE}", "start"]
13 changes: 0 additions & 13 deletions ui-applications/packages/back-office-ui/Dockerfile

This file was deleted.

13 changes: 0 additions & 13 deletions ui-applications/packages/gallery-ui/Dockerfile

This file was deleted.

1 change: 1 addition & 0 deletions ui-applications/packages/gallery-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@lens-up/shared-components": "file:../shared-components",
"@microsoft/signalr": "^8.0.0",
"@reduxjs/toolkit": "^2.2.3",
"framer-motion": "^11.1.7",
"localforage": "^1.10.0",
Expand Down
Loading