Skip to content

Commit

Permalink
Merge pull request #122 from episerver/feature/AFORM-4107-Create_musi…
Browse files Browse the repository at this point in the history
…c_festival_backend

Create music festival backend
  • Loading branch information
linhhoangOpti authored May 3, 2024
2 parents afddc93 + 9ef2a98 commit 961a8e6
Show file tree
Hide file tree
Showing 172 changed files with 1,276 additions and 1 deletion.
1 change: 1 addition & 0 deletions samples/musicfestival-backend-dotnet/. dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/*/*.mdf
600 changes: 600 additions & 0 deletions samples/musicfestival-backend-dotnet/.editorConfig

Large diffs are not rendered by default.

Empty file.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using EPiServer.Cms.Shell;
using EPiServer.Web;
using EPiServer.Web.Routing;
using Microsoft.AspNetCore.Mvc;
using Optimizely.Cms.Preview2.Content;
using Optimizely.Cms.Preview2.Content.Models;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace AlloyMvcTemplates.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ReactController : ControllerBase
{
private readonly IContentRepository _contentRepositoryInteApi;

public ReactController(IContentRepository contentRepositoryInteApi)
{
_contentRepositoryInteApi = contentRepositoryInteApi;
}

[HttpGet("GetFormInPageByUrl")]
public async Task<IActionResult> GetFormInPageByUrl(string url)
{
var builder = new EPiServer.UrlBuilder(url);
var content = UrlResolver.Current.Route(builder, ContextMode.Default);

if (content is null)
{
return NoContent();
}
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
var key = ContentKey.FormatAsKey(content.ContentGuid);
var pageModel = new PageModel();
var contentHeadless = await _contentRepositoryInteApi.GetAsync(key, content.LanguageBranch());

pageModel.Title = contentHeadless.DisplayName;
pageModel.PageUrl = UrlResolver.Current.GetUrl(content.ContentLink);

if (contentHeadless.Properties.ContainsKey("MainContentArea"))
{
pageModel.Childrens.AddRange(contentHeadless.Properties["MainContentArea"] as IList<IContentComponent>);
}

return Ok(pageModel);
}
}

public class PageModel
{
public string Title { get; set; }
public string PageUrl { get; set; }
public List<IContentComponent> Childrens { get; set; } = new List<IContentComponent>();
}
39 changes: 39 additions & 0 deletions samples/musicfestival-backend-dotnet/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Build image
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build

WORKDIR /app

COPY . .

RUN dotnet restore

RUN dotnet publish -c Release -o /out

COPY ./App_Data/DefaultSiteContent.episerverdata /out/App_Data/DefaultSiteContent.episerverdata
COPY ./App_Data/blobs_default /out/App_Data/blobs
COPY ./entrypoint.sh /out
COPY ./sshd_config /out

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime

WORKDIR /app

COPY --from=build /out .

ENV ASPNETCORE_URLS=http://+:80
ENV ASPNETCORE_ENVIRONMENT=Production

# Start and enable SSH
RUN apt-get update \
&& apt-get install -y --no-install-recommends dialog \
&& apt-get install -y --no-install-recommends openssh-server \
&& echo "root:Docker!" | chpasswd \
&& chmod u+x ./entrypoint.sh

COPY sshd_config /etc/ssh/

# Expose port 80 2222
EXPOSE 80 2222

#ENTRYPOINT ["dotnet", "MusicFestival.Backend.dll"]
ENTRYPOINT [ "./entrypoint.sh" ]
16 changes: 16 additions & 0 deletions samples/musicfestival-backend-dotnet/ImagePage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using EPiServer.Core;
using EPiServer.DataAnnotations;
using EPiServer.Framework.DataAnnotations;

[ContentType(GUID = "ef6bf538-025e-4981-af47-065c754c145b")]
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
public class ImagePage : ImageData
{
/// <summary>
/// Gets or sets the copyright.
/// </summary>
/// <value>
/// The copyright.
/// </value>
public virtual string Copyright { get; set; }
}
43 changes: 43 additions & 0 deletions samples/musicfestival-backend-dotnet/MusicFestival.Backend.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>MusicFestival.Backend</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<CmsUIVersion>12.26.0</CmsUIVersion>
<CmsCoreVersion>12.20.1</CmsCoreVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="EPiServer.CloudPlatform.Cms" Version="1.6.1" />
<PackageReference Include="EPiServer.CMS" Version="12.26.0" />
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.CMS.AspNetCore.HtmlHelpers" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.CMS.AspNetCore.MVC" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.CMS.AspNetCore.Routing" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.CMS.AspNetCore.Templating" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.CMS.Core" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.Framework" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.Framework.AspNetCore" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.Hosting" Version="$(CmsCoreVersion)" />
<PackageReference Include="EPiServer.CMS.UI" Version="$(CmsUIVersion)" />
<PackageReference Include="EPiServer.CMS.UI.Core" Version="$(CmsUIVersion)" />
<PackageReference Include="EPiServer.CMS.UI.VisitorGroups" Version="$(CmsUIVersion)" />
<PackageReference Include="EPiServer.CMS.UI.AspNetIdentity" Version="$(CmsUIVersion)" />
<PackageReference Include="EPiServer.ContentDefinitionsApi" Version="3.9.1" />
<PackageReference Include="EPiServer.ContentDeliveryApi.Cms" Version="3.9.1" />
<PackageReference Include="EPiServer.ContentDeliveryApi.Core" Version="3.9.1" />
<PackageReference Include="EPiServer.ContentManagementApi" Version="3.9.1" />
<PackageReference Include="EPiServer.OpenIDConnect" Version="3.9.1" />
<PackageReference Include="EPiServer.OpenIDConnect.UI" Version="3.9.1" />
<PackageReference Include="EPiServer.Forms" Version="5.8.0" />
</ItemGroup>

<ItemGroup Label="HeadlessForm">
<PackageReference Include="Optimizely.Headless.Form.Service" Version="0.1.0--inte-256" />
<PackageReference Include="Optimizely.Headless.Form.ContentGraph" Version="0.1.0--inte-256" />
<PackageReference Include="Optimizely.Cms.Preview2.Content.EPiServer" Version="12.20.1-ci-2644" />
<PackageReference Include="Optimizely.ContentGraph.Cms" Version="3.5.1" />
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions samples/musicfestival-backend-dotnet/MusicFestival.Backend.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 25.0.1700.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MusicFestival.Backend", "MusicFestival.Backend.csproj", "{F8DACC01-EB86-4323-B824-0860C9125019}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F8DACC01-EB86-4323-B824-0860C9125019}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8DACC01-EB86-4323-B824-0860C9125019}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8DACC01-EB86-4323-B824-0860C9125019}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8DACC01-EB86-4323-B824-0860C9125019}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0A1BEB8F-0A90-40CA-A587-4959F2EB9904}
EndGlobalSection
EndGlobal
17 changes: 17 additions & 0 deletions samples/musicfestival-backend-dotnet/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace MusicFestival.Backend;

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureCmsDefaults()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
60 changes: 60 additions & 0 deletions samples/musicfestival-backend-dotnet/ProvisionDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using EPiServer.Web;

namespace MusicFestival.Backend;

public class ProvisionDatabase : IHostedService
{
private readonly ILogger<ProvisionDatabase> _logger;
private readonly ISiteDefinitionRepository _siteDefinitionRepository;

public ProvisionDatabase(
ILogger<ProvisionDatabase> logger,
ISiteDefinitionRepository siteDefinitionRepository)
{
_logger = logger;
_siteDefinitionRepository = siteDefinitionRepository;
}

public async Task StartAsync(CancellationToken cancellationToken)
{
await AddPrimarySiteHost();
}

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

private Task AddPrimarySiteHost()
{
_logger.LogInformation("Provisioning primary site host.");

var site = _siteDefinitionRepository
.List()
.FirstOrDefault();

if (site is null)
{
_logger.LogInformation("Primary site host already exists.");

return Task.CompletedTask;
}
else
{
site = site.CreateWritableClone();
}

if (!site.Hosts.Any(x => x.Type == HostDefinitionType.Primary))
{
var editHost = site.Hosts.First(x => x.Name != "*");
editHost.Type = HostDefinitionType.Edit;

site.Hosts.Add(new HostDefinition
{
Type = HostDefinitionType.Primary,
Name = "localhost:3000"
});
}

_siteDefinitionRepository.Save(site);

return Task.CompletedTask;
}
}
65 changes: 65 additions & 0 deletions samples/musicfestival-backend-dotnet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Music Festival backend site
This is the backend site used to demonstrate On Page Editing feature with decoupled delivery site built with create-react-app script.
The backend site is built using Optimizely CMS 12 with ContentGraph integration packages installed.
You also need to run the react-script version of the frontend site in order to try out the on page editing feature.

## Prerequisites
This project uses:
* NET6.0
* SQL Server 2016 Express LocalDB ([download here](https://www.microsoft.com/en-us/sql-server/sql-server-downloads)). On macOS, we can use Azure SQL Edge instead ([Link](https://learn.microsoft.com/en-us/azure/azure-sql-edge/disconnected-deployment))

## Setup and Run

1. On Windows, run `setup.cmd`. You can re-run `setup.cmd` at any time to reset the backend with a fresh database.
* On Mac OS or linux, run `setup.sh` to setup blobs for backend site.
* If you are on MacOS, follow the guide below to setup database in an Azure SQL Edge container.
2. Config the Content Graph keys:
* ./appsettings.json
* Set "FRONT_END_URI" to "http://localhost:3000" which is the frontend site you will run later.

3. Setup your database server, on Windows you can use LocalDB and no setup is required, on MacOS, please refer to the section below to setup the DB in MacOS.

4. Open terminal for `./samples/musicfestival-backend-dotnet` and run `dotnet run`.
* Navigate to http://localhost:8082/.
* Create an admin user. If the UI is not displayed automatically, navigate to http://localhost:8082/util/register.
* Add the following config site if it doesn't exist
```
Name: MusicFestival.Backend
URL: http://localhost:8082
Start page: Root > Start
Host names
localhost:8082 - Edit
localhost:3000 - Primary
```
* Run the job `Content Graph content synchronization job` to index whole contents into the Content Graph for the first time
5. Afterwards, please follow the README for react-script frontend site to set it up. You can also run the Next.js version of the Music Festival frontend site.
## DB configurations
### Database connection string
* startup.cs is designed so that the site can start right away on both Windows and MacOS.
* You can also update your database connection string in appsettings.json.
* The backend is quite the same with the backend of the [content-delivery-js-sk](https://github.com/episerver/content-delivery-js-sdk/tree/master/samples/music-festival-vue-decoupled) except using Content Graph `services.AddContentGraph(_configuration, OpenIDConnectOptionsDefaults.AuthenticationScheme);`.
### Create database on MacOS using Azure SQL Edge on Docker
On MacOS, you cannot run SQL Server, an alternative is to run an Azure SQL Edge container in Docker.
* Run the following commands to start the container
```
docker run -e 'ACCEPT_EULA=1'-e 'MSSQL_SA_PASSWORD=Admin123! -p 1433:1433 --name azuresqledge -d mcr.microsoft.com/azure-sql-edge
```
* Run `docker cp db.mdf azuresqledge:/var/opt/mssql/data/musicfestival.mdf` at `App_Data` folder to copy the database file to the container.
* Update the file permission in the container
Run a terminal inside the AzureSQLEdge container
```
docker exec -it --user root azuresqledge bash
```
Then in the shell, change the file owner user and group
```
chown mssql:root /var/opt/mssql/data/musicfestival.mdf
```
* Use [Azure Data Studio](https://learn.microsoft.com/en-us/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver16#download-azure-data-studio) to connect to database and execute the query below to create database
`CREATE DATABASE MusicFestival ON (FILENAME = '/var/opt/mssql/data/musicfestival.mdf') FOR ATTACH;`
* Then the backend should be able to connect to the database running in the SQL instance inside the container.
Loading

0 comments on commit 961a8e6

Please sign in to comment.