[Code Pipeline x Elastic Beanstalk] Application Java CI / CD vers Elastic Beanstalk avec Code Pipeline, partie 1

Application pratique à l'application Java CI / CD (obtient la valeur de la base de données et renvoie le résultat au format JSON) à Elastic Beanstalk avec CodePipeline.

Parce que c'est long

Le contenu est divisé en 3 articles. Le temps de travail total est supposé être d'environ 3 heures, hors préparation préalable. Environ 1 heure pour chaque article est un guide.

environnement

Diagramme d'image

Ceci est une image approximative de ce que vous pouvez faire avec cette procédure. Lorsque vous transmettez le code modifié localement à Commit → CodeCommit, CodePipeline crée un mécanisme CI / CD qui se construit et se déploie automatiquement sur Elastic Beanstalk, qui est l'environnement d'exécution de l'application. image.png

Préparation préalable

① Si Eclipse n'est pas installé, Pleiades All in One Eclipse Download (Release 2020-06) | MergeDoc Project Veuillez télécharger la dernière version (au 3 août 2020). Avec STS et Lombok déjà configurés, vous pouvez commencer à développer avec Spring Boot tout de suite.

(2) JDK suppose Amazon Correto 8. Télécharger Amazon Corretto 8 | aws Veuillez télécharger → installer et compléter les paramètres pour Eclipse.

③ Pour que CodeCommit puisse être utilisé Comment utiliser AWS CodeCommit. D'où vous créez une clé d'accès. | Qiita Veuillez vous préparer à l'avance en vous référant à.

procédure

1. Création d'une application Java (Spring Boot)

Tout d'abord, créez une application Java (Spring Boot) dans Eclipse. Il est très simple d'obtenir des informations détaillées sur le magasin en fonction de l'identifiant du magasin. La structure du package est la suivante.

sample-eb-java
     |
    src/main/java
     |----jp.co.sample_eb_java
     |               |---- app
     |               |     |---- controller
     |               |     |---- response
     |               |
     |               |---- domain
     |               |      |---- service
     |               |      |---- repository
     |               |      |---- model
     |               |  
     |               |---- exception
     |               
     |
    src/main/resources
     |----application.yml
     |
    Buildfile
    Procfile
    build.gradle
    .ebextensions

・ ・ ・ Omis ci-dessous

[1] Création d'un projet

(1) Après avoir ouvert Eclipse, cliquez sur «Fichier» (①)> «Nouveau» (②)> «Projet» (③). image.png

(2) Au démarrage de l'assistant, sélectionnez «Spring Starter Project» (①) et cliquez sur «Next» (②). image.png

(3) Réglez comme indiqué dans la capture ci-dessous (1) et cliquez sur "Suivant" (2). image.png

(4) Vérifiez Lombok, le pilote MySQL, Spring Data JPA, Spring Web (si vous n'êtes pas candidat, veuillez rechercher dans le champ de recherche) et cliquez sur "Suivant" (②). image.png

[2] Modifier / créer un fichier de paramètres

Ensuite, modifiez et créez le fichier de paramètres.

(1) Renommez application.properties en application.yml et écrivez comme suit.

application.yml


spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${DB_HOST:nom d'hôte}:${DB_PORT:numéro de port}/${DB_NAME:Nom de la base de données}?serverTimezone=JST
    username: ${DB_USERNAME:Nom d'utilisateur}
    password: ${DB_PASSWORD:mot de passe}
  jpa:
    database: MYSQL
    hibernate.ddl-auto: none
server:
  port: ${SERVER_PORT:Numéro de port du serveur}

Je changerai la partie japonaise plus tard, alors laissez-la telle quelle.

(2) Créez un Buildfile dans le répertoire racine et décrivez comme suit.

Buildfile


build: ./gradlew assemble

(3) Créez un Procfile dans le répertoire racine et décrivez comme suit.

Procfile


web: java -jar build/libs/sample-eb-java.jar

(4) Ajouter à build.gradle. Trouvez la pièce avant l'ajout et ajoutez "bootJar.archiveName =" sample-eb-java.jar "".

build.gradle (avant ajout)


configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

build.gradle (après ajout)


configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
	bootJar.archiveName = "sample-eb-java.jar"
}

[3] Création du code source

Vient ensuite la création du code source. La structure du paquet est comme indiqué au début de ce chapitre (1. Créer une application Java (Spring Boot)), mais je pense qu'il serait gênant de revenir en haut, donc je publierai une capture. image.png

(1) Tout d'abord, la classe Entity. Il sortira plus tard, mais il correspond à la table shop_informations créée dans la base de données.

ShopInformation.java


package jp.co.sample_eb_java.domain.model;

import java.io.Serializable;
import javax.persistence.*;

import lombok.Getter;
import lombok.Setter;


/**
 *Classe d'entité liée à la table d'informations du magasin
 * 
 * @author CHI-3
 *
 */
@Entity
@Getter
@Setter
@Table(name="shop_informations")
@NamedQuery(name="ShopInformation.findAll", query="SELECT s FROM ShopInformation s")
public class ShopInformation implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="shop_id")
	private Integer shopId;

	private String access;

	private String address;

	@Column(name="business_hour")
	private String businessHour;

	@Column(name="regular_holiday")
	private String regularHoliday;

	@Column(name="shop_name")
	private String shopName;

	private String tel;

	@Column(name="zip_code")
	private String zipCode;

	public ShopInformation() {
	}

}

(2) Ensuite, l'interface du référentiel. L'interface utilisée pour les opérations de table.

ShopInformationRepository.java


package jp.co.sample_eb_java.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import jp.co.sample_eb_java.domain.model.ShopInformation;

/**
 *Interface de référentiel qui gère les informations du magasin
 *
 * @author CHI-3
 *
 */
@Repository
public interface ShopInformationRepository extends JpaRepository<ShopInformation, Integer>{

	/**
	 *Obtenir les informations du magasin liées à l'identifiant du magasin
	 *
	 * @param shopId ID de magasin
	 * @retourner les informations du magasin
	 */
	public ShopInformation findByShopId(Integer shopId);

}

(3) Ensuite, la classe Service. Fournit la logique.

ShopInformationService.java


package jp.co.sample_eb_java.domain.service;

import java.util.Optional;

import org.springframework.stereotype.Service;

import jp.co.sample_eb_java.domain.model.ShopInformation;
import jp.co.sample_eb_java.domain.repository.ShopInformationRepository;
import lombok.RequiredArgsConstructor;

/**
 *Classe de service pour obtenir des informations de magasin
 *
 * @author CHI-3
 *
 */
@Service
@RequiredArgsConstructor
public class ShopInformationService {

	private final ShopInformationRepository shopInformationRepository;

	/**
	 *Obtenir des informations sur le magasin
	 *
	 * @param shopId ID de magasin
	 * @retourner les informations du magasin
	 * @throws Exception
	 */
	public ShopInformation getShopInformation(Integer shopId) throws Exception{
		//Obtenir les informations du magasin: lancer une exception si le magasin cible n'existe pas
		ShopInformation shopInformation = Optional.ofNullable(shopInformationRepository.findByShopId(shopId)).orElseThrow(Exception::new);
		return shopInformation;
	}

}

(4) Ensuite, la classe Response. Nous moulerons la valeur à retourner.

ShopInformationResponse.java


package jp.co.sample_eb_java.app.response;

import jp.co.sample_eb_java.domain.model.ShopInformation;
import lombok.Builder;
import lombok.Getter;

/**
 *Classe de réponse pour l'acquisition d'informations de magasin
 * @author CHI-3
 *
 */
@Getter
@Builder
public class ShopInformationResponse {
	/**stocker des informations*/
	private ShopInformation shopInformation;
}

(5) Vient ensuite la classe Controller. J'utilise @RestController pour renvoyer la valeur au format JSON.

ShopInformationController.java


package jp.co.sample_eb_java.app.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import jp.co.sample_eb_java.app.response.ShopInformationResponse;
import jp.co.sample_eb_java.domain.model.ShopInformation;
import jp.co.sample_eb_java.domain.service.ShopInformationService;
import lombok.RequiredArgsConstructor;

/**
 *API pour obtenir des informations sur le magasin
 * 
 * @author CHI-3
 *
 */
@RestController
@RequiredArgsConstructor
public class ShopInformationController {

	private final ShopInformationService shopInformationService;

	/**
	 *Obtenir des informations sur le magasin
	 *
	 * @param shopId ID de magasin
	 * @return Response entity (stocker les informations)
	 * @throws Exception
	 */
	@GetMapping("/shop-information/{shopId}")
	public ResponseEntity<ShopInformationResponse> getShopInformation(@PathVariable("shopId") Integer shopId) throws Exception{
		ShopInformation shopInformation = shopInformationService.getShopInformation(shopId);
		ShopInformationResponse shopInformationResponse = ShopInformationResponse.builder().shopInformation(shopInformation).build();
		return new ResponseEntity<>(shopInformationResponse, HttpStatus.OK);
	}

}

(6) Enfin, ExceptionHandler. Cette classe gère les erreurs. Cette fois, lors de la demande d'un ID de magasin qui n'existe pas, une erreur 400 (mauvaise demande) sera renvoyée.

ExceptionHandler.java


package jp.co.sample_eb_java.exception;


import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import lombok.extern.slf4j.Slf4j;

/**
 *Gestionnaire d'exceptions
 *
 * @author CHI-3
 *
 */
@ControllerAdvice
@Slf4j
public class ExceptionHandler {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @org.springframework.web.bind.annotation.ExceptionHandler({Exception.class})
    public @ResponseBody
    ResponseEntity<Object> handleError(final Exception e) {
        log.info("call ExceptionHandler", e);
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }
}

[4] Création d'un fichier jar

(1) Créez un fichier jar pour créer l'environnement Elastic Beantalk. Accédez au répertoire racine de votre projet et exécutez la commande build. Si la mise en page est la suivante, ce sera comme suit. image.png

Commande d'exécution


> cd C:\pleiades-2020-03\workspace\sample-eb-java
> gradlew build

OK si le résultat est "BUILD SUCCESSFUL"! </ b>

(2) Assurez-vous que le fichier jar est créé sous build / libs. (Utilisez ceci lors de la création de l'environnement.) image.png

2. Créez un référentiel Git

Autorisez la gestion Git pour le projet créé à l'étape 1. Créez un référentiel local sur le projet créé à l'étape 1 et synchronisez-le avec le référentiel distant.

[1] Création d'un référentiel local

(1) Ouvrez l'invite de commande ou GitBash, déplacez (cd) vers le répertoire racine du projet créé en 1, puis initialisez le référentiel (exécutez la commande suivante).

> git init

OK si vous avez un dossier .git dans le répertoire racine de votre projet. image.png

(2) Réécrivez .gitignore avant de valider. Avec la description par défaut, les fonctions nécessaires telles que STS ne seront pas soumises à la validation et peuvent causer des problèmes tels que ne pas fonctionner plus tard. Modifiez la description comme suit. Ceux qui n'ont pas besoin d'être validés, tels que les fichiers de classe et les fichiers de verrouillage, sont exclus.

.gitignore


bin/*
.lock

(3) Validez vos modifications. C'est OK si vous exécutez les commandes suivantes dans l'ordre.

> git add .
> git commit -m "first commit"

La partie "premier commit" (message de commit) peut être n'importe quel contenu, mais faisons-en un message qui comprend le contenu édité (même ci-dessous)

(4) Modifiez à nouveau .gitignore. Décrit ce qui est nécessaire en tant que fonction mais n'est pas soumis à une validation locale.

.gitignore



# Created by https://www.toptal.com/developers/gitignore/api/java,gradle,eclipse
# Edit at https://www.toptal.com/developers/gitignore?templates=java,gradle,eclipse

### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# PyDev specific (Python IDE for Eclipse)
*.pydevproject

# CDT-specific (C/C++ Development Tooling)
.cproject

# CDT- autotools
.autotools

# Java annotation processor (APT)
.factorypath

# PDT-specific (PHP Development Tools)
.buildpath

# sbteclipse plugin
.target

# Tern plugin
.tern-project

# TeXlipse plugin
.texlipse

# STS (Spring Tool Suite)
.springBeans

# Code Recommenders
.recommenders/

# Annotation Processing
.apt_generated/
.apt_generated_test/

# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet

# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project

### Eclipse Patch ###
# Spring Boot Tooling
.sts4-cache/

### Java ###
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

### Gradle ###
.gradle
build/

# Ignore Gradle GUI config
gradle-app.setting

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Cache of project
.gradletasknamecache

# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties

### Gradle Patch ###
**/build/

# End of https://www.toptal.com/developers/gitignore/api/java,gradle,eclipse
  • Java
  • Gradle
  • Eclipse

A été créé comme condition.

Lorsque vous avez terminé vos modifications, validez-les.

> git add .gitignore
> git commit -m "fix .gitignore"

(5) Changez l'autorité de gradlew. [Important] Si vous ignorez cette étape, une erreur se produira lors de la génération et du déploiement, alors assurez-vous de l'exécuter. </ b>

Tout d'abord, vérifiez les autorisations de gradlew.

> git ls-files -s gradlew
100644 fbd7c515832dab7b01092e80db76e5e03fe32d29 0       gradlew

Si vous conservez ce qui précède, vous n'avez que l'autorisation de lecture, alors exécutez la commande suivante pour donner l'autorisation d'exécution.

> git update-index --add --chmod=+x gradlew

Une fois l'exécution terminée, vérifions à nouveau l'autorité. Comme indiqué ci-dessous, il est OK si les 3 derniers chiffres des 6 premiers chiffres sont 755.

> git ls-files -s gradlew
100755 fbd7c515832dab7b01092e80db76e5e03fe32d29 0       gradlew

Validez vos modifications.

> git add gradlew
> git commit -m "fix permission of gradlew"

[2] Création d'un référentiel distant

(1) Connectez-vous à AWS Management Console, recherchez CodeCommit dans «Services» (①) et cliquez sur (②). image.png

(2) Après être passé à la page CodeCommit, cliquez sur "Créer un référentiel". image.png

(3) Donnez un nom de référentiel avec le même nom que le projet créé à l'étape 1 (1), et cliquez sur «Créer». image.png

[3] Synchronisez les référentiels locaux et distants

(1) Lorsque la création du référentiel distant est terminée, la page suivante s'affiche. Cliquez sur "Clonage d'URL" (1)> "Clonage HTTPS" (2). image.png

(2) Ouvrez l'invite de commande ou GitBash et exécutez la commande suivante dans le répertoire racine du projet.

> git remote add origin (1)URI copié dans "HTTPS clone"

(3) Poussez le contenu vers le maître du référentiel distant.

> git push -u origin master

(4) Sur la console, vérifiez que le contenu du référentiel local est reflété dans le référentiel distant. image.png

À propos de la suite

La continuation

À. 3. Créez l'environnement Elastic Beanstalk, 4. Configurez la connexion à la base de données.

Journal des modifications

--2020 / 08/13: Ajout de "[4] Créer un fichier jar" à la procédure "1. Créer une application Java (Spring Boot)"

référence

environnement

procédure

1. Création d'une application Java (Spring Boot)

2. Créez un référentiel Git

Recommended Posts