Redis v kontejneru

Redis (zkratka z anglického „Remote Dictionary Server“) je open-source in-memory key-value úložiště (NoSQL databáze) s otevřeným zdrojovým kódem. Redis byl původně vytvořen jako rychlý a efektivní způsob ukládání a získávání dat v paměti (in-memory database) pro zlepšení výkonu webových aplikací. Často se používá pro ukládání cache.

In-Memory storage: Redis ukládá data přímo v paměti, což ho dělá extrémně rychlým. To z něj činí vhodný nástroj pro cache, rychlé ukládání a získávání dat a další aplikace, které vyžadují nízkou latenci.

Key-Value store: Redis ukládá data ve formátu klíč-hodnota, to znamená, že každý záznam má jedinečný klíč, pod kterým je uložen. Data jsou obvykle binární nebo textové, a Redis umožňuje rychlé vyhledávání a získávání dat na základě klíče.

Podpora datových struktur: Redis nepodporuje pouze jednoduché hodnoty, ale také různé datové struktury jako seznamy, množiny, hashovací mapy a další. To umožňuje složitější operace s daty a efektivní manipulaci s nimi.

Pub/Sub mechanismus: Redis umožňuje publikování a odběr zpráv, to je užitečné pro asynchronní komunikaci mezi částmi aplikace.

Perzistence dat: Redis umožňuje volitelnou perzistenci dat na disk, což zajišťuje, že data nejsou ztracena po restartu serveru.

Clustering: Redis podporuje klustering, to umožňuje škálovat databázi na více serverů a zlepšit výkon a dostupnost.

Redis je často používán pro ukládání chache, asynchronní fronty zpráv, čítačky stavů a mnoho dalších aplikací, které vyžadují rychlé ukládání a získávání dat. Jeho jednoduchý a efektivní design ho činí oblíbeným nástrojem pro vývojáře v celé řadě aplikací a scénářů.

Založíme soubor docker-compose.yml :

version: '3.8'

services:
  redis:
    image: "redis:latest"
    container_name: redis
    ports:
      - "6379:6379"

Spustíme příkazem: docker-compose up nebo na pozadí příkazem: docker-compose up -d

RabbitMQ v kontejneru

Dnes si ukážeme jak jednoduše rozject RabbitMQ v dokcer kontejneru. Pro orchestraci použijeme docker compose.

Založíme soubor docker-compose.yml :

version: '3.4'

services:

  rabbitmq:
    image: rabbitmq:3-management
    hostname: "rabbitmq"
    labels:
      NAME: "rabbitmq"
    ports:
      - "4369:4369"
      - "5671:5671"
      - "5672:5672"
      - "25672:25672"
      - "15671:15671"
      - "15672:15672"
    environment:
      RABBITMQ_DEFAULT_USER: "username"
      RABBITMQ_DEFAULT_PASS: "password"

Spustíme příkazem: docker-compose up nebo na pozadí příkazem: docker-compose up -d

RabbitMQ je message broker, který používá protokol AMQP (Advanced Message Queuing Protocol) k usnadnění komunikace mezi různými aplikacemi. RabbitMQ běží na určitých síťových portech, které jsou důležité pro jeho funkčnost a komunikaci. Zde jsou některé z portů, které RabbitMQ používá:

4369: Tento port je používán pro Erlang Port Mapper Daemon (EPMD). EPMD je procesový démon, který umožňuje komunikaci mezi různými uzly v distribuovaném Erlangu, což je jazyk, na kterém je postaven RabbitMQ.

5671: Tento port je také asociován s AMQP, ale používá zabezpečený protokol SSL/TLS pro šifrovanou komunikaci. Je vhodné použít tento port pro bezpečnou komunikaci přes AMQP.

5672: Toto je výchozí port pro běžné spojení AMQP v RabbitMQ. Pokud není specifikován jiný port, klienti budou komunikovat přes tento port.

25672: Tento port je určen pro meziserverovou komunikaci mezi uzly v clusteru RabbitMQ, pokud je váš RabbitMQ nasazen jako cluster.

15671: Stejně jako port 5671, tento port umožňuje zabezpečenou komunikaci pomocí SSL/TLS, ale je určen pro webové rozhraní RabbitMQ Management Plugin.

15672: Toto je port pro RabbitMQ Management Plugin, což je webové rozhraní pro správu RabbitMQ. Pomocí tohoto rozhraní můžete monitorovat a spravovat své RabbitMQ instance.

Do webového rozhraní tedy můžeme nahlédnout přes URL http://localhost:15672

Defaultní uživatelské jméno: guest a heslo: guest
My jsme si změnili uživatelské jméno: user a heslo: password

C# Dynamický datový typ

Objčas potřebujeme udělat dynamicky malý objekt, kterému nastavíme parametry a pošleme ho dál. Ano, je to ošklivé, nemělo by se to dělat ale občas se to prostě hodí 🙂

dynamic flowCalculator = new
{
   Medium = inputData.HeaterEnum.ToString(),
   WaterTempIn = 80,
   WaterTempOut = 60

};

Jednoduše do toho dynamicky vygenerovaného objektu můžeme přidat další propertu:

if (inputData.MediumEnum == Medium.GLYCOL)
{
   flowCalculator.Concentration = inputData.Concentration;
}

System.Text.Json deserializace case insensitive

V C# objektu nazýváme property PascalCase s velkým písmenem na začátku.

    public class StudentDto
    {

        public long Id { get; set; }
        public string FirstName { get; set; }
        public double LastName { get; set; }
    }

Pokud na tento objekt chceme namapovat json, většinou narazíme na problém s rozdnou velikostí písmen a property se z jsonu nenamapují:

json:

{
    "id": 1,
    "firstName": "Jan",
    "lastName": "Novák"

}

Desertializace:

var student = JsonSerializer.Deserialize<Student>(jsonString);

Property v objektu zůstanou prázdné, protože nedošlo k namapování z jsonu (rozdílná velikost písmen)

Deserializace jsonu case insensitive

Serializeru můžeme nastavit propertu aby nerozlišoval velokost písmen:

var options = new JsonSerializerOptions 
{ 
    PropertyNameCaseInsensitive = true 
}; 

var student = JsonSerializer.Deserialize<Student>(jsonString, options);

Inastalace Camunda v kontejneru

Camunda je engine pro procesní řízení.

Business Process Model and Notation (BPMN) – notace pro modelování procesů.

Aktuálně je Camunda ve verzi 7 (comunity) a verzi 8 (enterpise – placená).

Pojďme si ukázat jak ji jednoduše zprovoznit v kontejneru Camunda 7.

docker pull camunda/camunda-bpm-platform:run-latest
docker run -d --name camunda -p 7777:8080 camunda/camunda-bpm-platform:run-latest

Na výsledek se můžeme podívat: http://127.0.0.1:7777/camunda-welcome/index.html

Defaultní přístupové údaje:

  • Username: demo
  • Password: demo

Camunda REST API + SWAGGER

Camunda se skládá z několika modulů

  • web-app – (balíčky: Tasklist, Cockpit a Admin)
  • rest – REST API
  • swaggerui – swagger UI rozhraní – dokumentace k REST API endpointům s možností otestování

Pokud potřebujeme používat REST API spustíme kontejner s požadovanými parametry:

docker pull camunda/camunda-bpm-platform:latest
docker run -d --name camunda -p 7777:8080 camunda/camunda-bpm-platform:latest ./camunda.sh --webapps --rest --swaggerui

APP: http://127.0.0.1:7777/camunda-welcome/index.html
API: http://127.0.0.1:7777/engine-rest/
Swagger: http://127.0.0.1:7777/swaggerui/

Defaultní přístupové údaje:

  • Username: demo
  • Password: demo

Quasar

Inicializace projektu

$ npm i -g @quasar/cli 
$ npm init quasar

Spuštění projektu

cd projek-folder
quasar dev

Nová komponenta

quasar new component <name> [--format ts]

Boot soubor

quasar new boot <name> [--format ts]

Základní příkazy

$ quasar
   ...
   Commands
      init       Create a project folder
      dev       Start a dev server for your App
      build       Build your app for production
      clean       Clean all build artifacts
      new       Quickly scaffold page/layout/component/... vue file
      mode       Add/remove Quasar Modes for your App
      info       Display info about your machine and your App
      serve       Create an ad-hoc (production-ready) server on App distributables
      help       Displays this message

Vue.js 3 – Hello world

npm create vue@3

Budeme vyzváni k zadání:

  • názvu projektu
  • podpory TypeStcriptu
  • podpory JSX
  • testů, ESlintu, …

Po vytvoření kostry projektu stačí nainstalovat balíčky a projekt spustit:

cd vue-project
npm install
npm run dev

Tip

Pokud se při spuštění vyskytnou problémy (failed to load config from vite.config.js, Error: Cannot find module ‚node:url‘, …) aktualizujte node.js na najnovější LTS verzi.

Spuštění projektu

Pokud vše prošlo, uvidíte v konzoli:

VITE v4.0.4 ready in 307 ms

➜ Local: http://localhost:5173/
➜ Network: use –host to expose
➜ press h to show help

Otevřee internetový prohlížeč a zadejte do něj adresu z konzole: http://localhost:5173/

React – Hello world

Vygenerování nové aplikace:

npx create-react-app hello-world

Spustit příkazem:

cd hello-world
npm start

Komponenty

npx generate-react-cli component Box

Do app.js přidat:

import Box from './components/Box/Box';
...
  return (
    <div className="App">
      <header className="App-header">
        <Box></Box>
      ...

npm start
Starts the development server.

npm run build
Bundles the app into static files for production.

npm test
Starts the test runner.

npm run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!

C# serializace a deserilizace výčtového typu

V C# se při serializaci a deserializaci JSON velmi často potřebujeme vypořádat s výčtovými typy (enum). Ve výchozím nastavení je hodnota z výčtového typu interpretována jako celé číslo – to většinou nestačí, protože požadujeme textovou hodnotu. Pojďme si ukázat, jak to vyřešit nativní knihovnou System.Text.Json a knihovnou Newtonsoft.Json

public class Student
{
    public string Name { get; set; }
    public SexEnum Sex { get; set; }

}

public enum SexEnum 
{
    Female, Male
}

var student1 = new Student() { Name = "Pepek Vyskoc", Sex = SexEnum.Male }

// Native serialize
JsonSerializer.Serialize(student1);

// Newtonsoft
return JsonConvert.SerializeObject(student1);

Vrátí json:

{
  "Name": "Pepek Vyskoc",
  "Sex": 1
}

Funkční ale dost často nedostačující, protože z pohlaví 0 a 1 toho moc nepoznáme.

Serializace enum jako textový řetězec

Stačí přidat k požadované propertě anotaci *EnumConverter:

// Native
public class Student
{
    ...
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public SexEnum Sex { get; set; }
    ...
}
// Newtonsoft
public class Student
{
    ...
    [JsonConverter(typeof(StringEnumConverter))]
    public SexEnum Sex { get; set; }
    ...
}

Kde získáme požadovaný formát odpovědi:

{
  "Name": "Pepek Vyskoc",
  "Sex": "Male"
}

Globální serializace enum jako textový řetězec

Pokud nechcete před každou propertu uvádět anotaci pro converter, máte možnost ji nastavit globálně do souboru Program.cs:

// Native
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    });

// Newtonsoft
builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.Converters.Add(new StringEnumConverter());
    });

Tím dosáhneme požadovaného výsledku automaticky

.Net + EF core – database first – MySql

Entity Framework je populární ORM (Object-Relational Mapping) framework pro aplikace v .NET, který vám umožňuje pracovat s databází. Při použití Entity Frameworku, si můžete vybrat mezi dvěma hlavními přístupy: Code First a Database First. V tomto případě chcete pracovat s databází MySQL pomocí přístupu Database First, což znamená, že generujete třídy entit z existující databáze. Vygenerování modelových tříd z DB tabulek se nazývá scaffolding. Dnes si ukážeme jak toho dosáhnout v .NET6 a Entity Frameworku pro MySql databázi.

Přes Package Manager Console nainstalujte Entity Framework Core a MySQL Provider

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Pomelo.EntityFrameworkCore.MySql

Vygenerujeme entity z tabulek DB

Použijte Entity Framework Core CLI k vytvoření databáze. Otevřete příkazový řádek, přejděte do adresáře vašeho projektu a použijte:

dotnet ef dbcontext scaffold "server=localhost;user=root;password=xxx;database=app_cz" "Pomelo.EntityFrameworkCore.MySql" --output-dir Models -f

Tím pro každou tabulku vygenerujeme do složky Models odpovídající modelovou třídu a DbContex soubor (v našem případě AppCzContext.cs)

Pozor: ve vygenerovaném AppCzContext.cs je automaticky doplněn server a přístupové údaje k DB. Není vhodné tyto údaje na tomto místě držet, měly by se načítat z appsettings.json. Ale o tom zase někdy příště 🙂

Jednoduché použití DbContextu

Získáme všechny uživatele:

using (var dbContext = new AppCzContext())
{
   var users = dbContext.Users.ToList();
}

Pozor: jedná se o jednoduchou ukázku. Lepší řešení je si přes DI injecntou DB context. Ale o tom zaseněkdy příště