Ana içeriğe geç

1. Eksen#

EKSEN ismini verdiğimiz yazılım geliştirme altyapımız , microservices mimari prensiplerinden, modülerlik, sürekli otomasyon, gizli uygulama erişimi, merkezileştirmekten kaçınmak, bağımsız kurulum, hata durumlarının yönetimi, gözlenebilirlik ile ilgili entegre çözümler barındırmaktadır.

EKSEN, Tüm Kamu Kurum ve Kuruluşlarımızın yabancı ürünlere ödediği lisans maliyetlerinin sıfırlanması ve Yurtdışı bağımlılıklarımızın yok edilmesi hedeflenerek geniş kabul gören, olgunluğunu ispatlayarak defacto haline gelmiş açık kaynak kodlu yazılımları kullanarak geliştirmiş olduğumuz yazılım geliştirme altyapısıdır.


Genel İçerigi#

  • Yerli ve milli yazılım vizyonu ile açık kaynak(open source) teknolojiler kullanılarak geliştirilmiştir.
  • Programlama dili olarak Java dilinin güncel versiyonu kullanılmaktadır.
  • Java uygulaması geliştirmek için Spring Boot Framework kullanılmaktadır.
  • Microservices mimariye uygun uygulama geliştirmeler için Spring Cloud Framework kullanılmaktadır
  • Java dili ile geliştirme yapıldığında kullanılan popüler açık kaynak farklı kütüphaneler de kullanılmaktadır. (apache, querydsl, mapstruct vb.)
  • Kendi teknoloji havuzumuzla entegre çalışması için özelleştirilmiş katmanlar(servis ve model contributer) eklenmiştir.
  • Güvenlik mimarisi olarak OAuth standartları uygulanmaktadır.
  • Veri tabanı işlemleri için JPA&QueryDSL kullanılmaktadır.
  • Cache ve Veri Tarihçesi gibi işlemler için altlıklar sağlanmaktadır.

Projelerin ortak yanları olan ve genelde en fazla kaynak harcanan parçaları olan altyapı bileşenleri her proje için tekrar geliştirilmekte ve test edilmektedir. Ekibimizin bir diğer ana görevi altyapı bileşenlerini küçük ve büyük proje farkı gözetmeksizin geliştirip test edilmiş güvenli bir altyapı hizmeti sunmaktır.

Kullanılan açık kaynak teknolojilerin yeni versiyonlarına hızlı bir şekilde geçiş yapılabilecek bir yapı sunulmaktadır. Aynı zamanda yeni çıkan açık kaynak yapılar incelenerek hızlı bir şekilde altyapımıza entegre edilmektedir.


Genel Yapı Ve Paketler#

Framework instance projelerinin genel yapısı 4 temel bileşenden oluşmaktadır.

  • Client
  • Provider
  • Starter
  • Server

Project Structure

Client#

İstemci tarafından erişilecek feign uçlarını içeren pakettir. FeignRestService'ler bu katmanda tanımlanır.


Provider#

Veri sağlanan işlerin yapıldığı katmandır. Database, redis, integration vb. üzerinden veri alışverişi işlemleri bu katmanda yapılır.

Örnek olarak database-provider modüle ait aşağıdaki paketleri içerir;

  • Converter -> Java bean'lerin dönüşümünü sağlamak amacı ile code generator olarak MapStruct kullanılmaktadır.
  • Entity -> Veritabanı tablolarına persistence domain nesnesidir.
  • Generator -> Sorgu kriterlerinin oluşturulmasına yardımcı olan sınıflardır.
  • Logic -> Repository erişimlerinin ve entity-model dönüşümlerinin yapıldığı servisleri içerir.
  • Repository -> Veritabanı işleri için kullanılan arayüzlerdir.


Starter#

Domain ile ilgili logic barındıran katmandır.

Modüle ait aşağıdaki paketleri içerir;

  • Controller -> Rest service implementasyonlarının yapıldığı sınıflardır. RestController'lar bu paket içerisinde yer alır.
  • Logic -> Domain logic içeren servisleri barındırır.

Modül ile ilgili ekstra özelliklere ihtiyaç duyulduğunda customization yapılabilecek olan pakettir. Kullanımı ile ilgili ayrıntılı bilgiye starter üzerinden ulaşılabilir.


Server#

İlgili instance için server'ın ayağa kaldırılması gerekmektedir. Bütün paketleri bir araya getirerek uygulamaya dönüştüren katmandır. Instance'a ait konfigürasyonlar bu katmanda yapılır. Profil ve taranacak olan paketler belirlenir.


Genel Bileşenler#

Framework#

Uygulama geliştirilirken başta Spring olmak üzere third-party temel bileşenleri gereksinimlere göre özelleştirilmiş olarak hizmete sunan altyapı bileşenidir. Configuration, swagger, exception, initializer, util vb. temel bileşenleri içermektedir. Bu altyapı bileşeni ihtiyaçlar doğrultusunda genişletilebilmektedir.


Actuator #

import tr.com.havelsan.javarch.actuator.annotation.HvlActuatorService;

@HvlActuatorService(name = "hvlBpmnIntegrationRestService", groupName = "hvlBpmnIntegration")

Uygulamada rest uçlarının, modellerinin bilgilerinin dönülmesini sağlamaktadır. Bu bilgileri alabilmek için ilk olarak ip:port/actuator adresine istek atmalısınız.

Servis bilgilerini alabilmeniz için aşağıdaki uçları kullanmanız gerekmektedir.

Service Endpoints

Model bilgilerini alabilmeniz için aşağıdaki uçları kullanmanız gerekmektedir.

Model Endpoints

TS-Generator ürünümüz type-script sınıflarını üretmek için yukaridaki uçları kullanmaktadır. Java temel annotation, model ve servis sınıflarının type-script'i üretilmektedir.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-management.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-actuator'


Configuration #

import tr.com.havelsan.javarch.configuration.HvlBaseConfiguration;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Configuration extends HvlBaseConfiguration {

}

Temel konfigurasyon sınıfı sunulmaktadır. Bu sınıftan türeyen sınıflar context'e dahil edildiğinde log atılmaktadır. Aynı zamanda scan etme işlemlerinde sadece konfigurasyon taranması için ayraç olarak kullanılabilmektedir.

Yaml veya properties dosyalarından konfigurasyonlarını ayrıştırmak için HvlPropertyParser sınıfı kullanılmaktadır. Bu sınıf sayesinde iç içe konfigurasyon verilmesi sağlanmaktadır.

service:
  url: ${service.url:${default.url}}

Konfigurasyonları şifreleme yeteneği bulunmaktadır. (jasypt kullanılmaktadır.) Şifreleme yeteneği sağlanan türleri:

  • pbes
  • standart_pbes
  • pooled_pbes
  • asymetric

NOT: Şifreleme işlemi StringEncryptor ile yapılmaktadır. Jasypt standartları ile şifreleme işlemi yapmak isterseniz StringEncryptor sınıfı kullanılabilir.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-instance.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-configuration'
    group: 'tr.com.havelsan.framework', name: 'hvl-configuration-encryptor'


Context #

Uygulama içeriğinde Bean, Environment ve System enviroment'a ulaşmamızı sağlamaktadır.

İki şekilde kullanılabilmektedir:

  • DI (Dependency Injection) ile kullanılabilir.
import org.springframework.stereotype.Component;
import tr.com.havelsan.javarch.context.HvlApplicationContext;

@Component
public class SampleService {

    private final HvlApplicationContext applicationContext;

    public SampleService(HvlApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void test() {
        applicationContext.getBean(SampleService.class);
        applicationContext.getEnvironment();
        applicationContext.getSystemLocale();
    }

}
  • Bean olmayan sınıflar statik olarak 'Holder' üzerinden kullanılabilir.
import tr.com.havelsan.javarch.context.holder.HvlApplicationContextHolder;

import java.util.Objects;

public final class SampleService {

    public static SampleService INSTANCE;

    public static SampleService getInstance() {
        if (Objects.isNull(INSTANCE)) {
            INSTANCE = new SampleService();
        }
        return INSTANCE;
    }

    public static void test() {
        HvlApplicationContextHolder.getBean(SampleService.class);
        HvlApplicationContextHolder.getEnvironment();
        HvlApplicationContextHolder.getSystemLocale();
    }

}

Uygulama içerisinde Bean'ler arası event mekanızmasına destek sağlamaktadır. Bunun için HvlApplicationEventListener ve HvlApplicationEventPublisher sınıfları kullanılmaktadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-context.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-context'


Crypto #

Uygulamada şifreleme işlemlerinde kullanılmaktadır. (Örneğin veritabanı kolonlarında şifreleme vb.) Güncel sürümde AES destek verilmektedir.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tr.com.havelsan.javarch.context.holder.HvlApplicationContextHolder;
import tr.com.havelsan.javarch.crypto.data.HvlCryptoType;
import tr.com.havelsan.javarch.crypto.service.HvlCryptoServiceBuilder;

/**
 * @author javarch
 */
@SpringBootApplication
public class HvlSampleApplication {


    public static void main(String[] args) {
        SpringApplication.run(new Class[]{HvlSampleApplication.class}, args);

        final HvlCryptoService aesCryptoService =
                HvlCryptoServiceBuilder.create(HvlCryptoType.AES).setKey("aesKey").build();
        final String encryptText = aesCryptoService.encrypt("test");
        final String decryptText = aesCryptoService.decrypt(encryptText);
    }

}

drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-crypto'


Exception #

Altyapıdan checked ve unchecked exception kullanımı sağlanmaktadır. Bu sınıflar HvlCheckedException ve HvlUncheckedException sınıflarıdır.

Exception sınıfları içerisinde HvlErrorDetail nesnesi bulunmaktadır. Bir isteğin yaşam döngüsü boyunca hata alması durumunda HvlErrorDetail alanı ile bilgi dönülmektedir.


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-exception'


Initializer #

// TODO yazılmalı mı?


Service #

Uygulamadan dışarıya açılan servis uçları (Rest Controller) buradan konfigure edilmektedir. (Örneğin serialization kuralları, gzip, cors, cookie vb.)

HvlHttpHeader sınıfında altyapının isteklerde (Http request) ve cevaplarda (Http response) kullandığı özel 'header' alanları bulunmaktadır.

Uygulamada istekle (Http request) ilgili bilgilere anlık ulaşabilmek için HvlServiceContext ve HvlServiceContextHolder sınıfları bulunmaktadır.

HvlServiceContextHolder kullanım örneği:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tr.com.havelsan.javarch.service.context.holder.HvlServiceContextHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author javarch
 */
@SpringBootApplication
public class HvlSampleApplication {


    public static void main(String[] args) {
        SpringApplication.run(new Class[]{HvlSampleApplication.class}, args);

        final HttpServletRequest servletRequest = HvlServiceContextHolder.getServletRequest();
        final HttpServletResponse servletResponse = HvlServiceContextHolder.getServletResponse();
    }

}

HvlServiceContext kullanım örneği:

import org.springframework.stereotype.Service;
import tr.com.havelsan.javarch.service.context.HvlServiceContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class SampleService {

    private final HvlServiceContext serviceContext;

    public SampleService(HvlServiceContext serviceContext) {
        this.serviceContext = serviceContext;
    }

    public void test() {
        final HttpServletRequest servletRequest = serviceContext.getServletRequest();
        final HttpServletResponse servletResponse = serviceContext.getServletResponse();
    }

}

Uygulamadan dışarıya açılan servis uçlarının (Rest Controller) döneceği verileri standartlaştırmak için HvlResponse ve HvlResponseEnttiy sınıfları bulunmaktadır. Bu sınıflar sayesinde payload, header, errorDetail gibi alanlar iştemciye standart olarak dönülmektedir.

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tr.com.havelsan.javarch.service.data.HvlResponse;
import tr.com.havelsan.javarch.service.data.HvlResponseEntity;

@RestController
@RequestMapping("/sample")
public class SampleController {

    @GetMapping(path = "/response", produces = MediaType.APPLICATION_JSON_VALUE)
    public HvlResponse<String> response() {
        return new HvlResponse<>("Response sample");
    }

    @GetMapping(path = "/response-entity", produces = MediaType.APPLICATION_JSON_VALUE)
    public HvlResponseEntity<String> responseEntıty() {
        return new HvlResponseEntity<>("Response entity sample");
    }

}

Uygulamadan dışarıya açılan servis uçlarının (Rest Controller) hata fırlatması (throw) durumunda hataya özgü ' HttpStatus' bilgisini cevaba (Http response) eklemeyi sağlayan yapı bulunmaktadır.

import org.springframework.http.HttpStatus;
import tr.com.havelsan.javarch.exception.HvlCheckedException;
import tr.com.havelsan.javarch.exception.model.HvlErrorDetail;
import tr.com.havelsan.javarch.service.annotation.HvlExceptionHttpStatus;

@HvlExceptionHttpStatus(code = HttpStatus.BAD_REQUEST)
public class SampleInvalidRequestException extends HvlCheckedException {

    public static final String ERROR_CODE = "code";

    public static final String ERROR_MESSAGE = "message";

    public SampleInvalidRequestException() {
        super(ERROR_MESSAGE, new HvlErrorDetail(ERROR_CODE, ERROR_MESSAGE));
    }

    public SampleInvalidRequestException(HvlErrorDetail errorDetail) {
        super(errorDetail);
    }

}

HvlRestExceptionHandler sınıfı ile sistemde handle edilen veya edilmeyen hatalar filitrelenip gerekli standartlara göre istemciye dönülmektedir. (HvlResponse ve HvlResponseEntity olarak) Burada geliştirici tarafında yutulan hatalar ele alınmamaktadır.

HvlCookieUtil sınıfı ile 'cookie' ile ilgili hizmetler sunulmaktadır. Örnek kullanım:

import org.springframework.stereotype.Service;
import tr.com.havelsan.javarch.service.configuration.properties.HvlCookieProperties;
import tr.com.havelsan.javarch.service.context.HvlServiceContext;
import tr.com.havelsan.javarch.service.util.HvlCookieUtil;

@Service
public class SampleService {

    private final HvlServiceContext serviceContext;

    public SampleService(HvlServiceContext serviceContext) {
        this.serviceContext = serviceContext;
    }

    public void test() {
        HvlCookieUtil.addCookie(serviceContext.getServletResponse(),
                "cookieName",
                "cookieValue",
                new HvlCookieProperties());
    }

}

ÖNERİ: Bean kullanımlarında servis arayüz sınıflarında @Validated ve @Valid annotationları kullanılmalıdır. Arayüz içerisindeki metotlarada gerekli validasyon annotationları konulmalıdır. Böylece metot içerisindeki, iş mantığı çalışmadan kaynak tüketmeden önce direk uygun olmadığı için metot içerisine girmeden validasyondan geri döner.

import org.springframework.validation.annotation.Validated;
import tr.com.havelsan.javarch.data.commons.pageable.HvlPage;
import tr.com.havelsan.javarch.samples.jpa.data.entity.HvlJpaSample;
import tr.com.havelsan.javarch.samples.jpa.data.model.HvlJpaSampleModel;
import tr.com.havelsan.javarch.samples.jpa.data.model.query.HvlJpaSampleQueryModel;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.util.List;

@Validated
public interface HvlSampleService {

    HvlJpaSampleModel save(@Valid @NotNull HvlJpaSampleModel sampleModel);

    HvlJpaSampleModel update(@Valid @NotNull HvlJpaSampleModel sampleModel);

    void deleteById(@NotNull @Positive Long id);

    List<HvlJpaSampleModel> getList();

    List<HvlJpaSampleModel> queryList(HvlJpaSampleQueryModel sampleQueryModel);

    List<HvlJpaSampleModel> queryList(HvlJpaSampleQueryModel queryModel, String locale);

    HvlPage<HvlJpaSampleModel> queryPage(HvlJpaSampleQueryModel sampleQueryModel);

    List<HvlJpaSample> getAllSample();

    void saveAll();

    void updateAll();

    void deleteAll(List<HvlJpaSample> entities);

}

drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-service.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-service'


Swagger #

Uygulamada swagger konfigurasyonları yapılmaktadır. Cloud ve Boot için destek sağlanmaktadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-swagger.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-swagger'


Util #

Uygulama geliştirirken genel destek sınıfları sunulmaktadır. Destek sınıfları:

  • Sertifika işlemleri için HvlCertificateUtil
  • Cron işlemleri için HvlCronUtil
  • IP ayrıştırma işlemleri için HvlIPUtil
  • String işlemleri için HvlStringUtil

drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework', name: 'hvl-util'


Cloud Framework#

Uygulamaları cloud yapısına uygun şekilde geliştirmek için hizmete sunulan altyapı bileşenidir. Temel teknoloji bileşenleri olarak OpenFeign, Spring Cloud kullanılmaktadır. Exception handling, tracing, registry integration vb. bileşenleri içermektedir. Bu altyapı bileşeni ihtiyaçlar doğrultusunda genişletilebilmektedir.


Configuration #

Mikro servis mimaride çok sayıda uygulama dağıtık mimaride bulunmaktadır. Bu durum uygulamalar ayağa kalkarken gerekli konfigurasyonu nasıl vereceğimiz problemini doğurmaktadır. Altyapı config-server entegrasyonu ile konfigurasyonlar için tek kaynaktan beslenme sağlanmıştır.

config-server kullanılırken dikkat edilmesi gereken konular bulunmaktadır. Dikkat edilmesi gereken konular:

  • Uygulamada resources altında bulunan .yml uzantılı dosyalar eğer config-server üzerinden gelmiyorsa kullanılabilir. config-server üzerinden gelen özellikler ve dosyalar baskınlık göstermektedir.
  • Uygulama ayağa kaldırılırken enviroment olarak verilen özelliklerde config-server üzerinden gelen özellikleri ezmektedir.
  • config-server üzerinden override edilmiş özellikler herhangi bir şekilde ezilemez. Özelliğin her uygulama için aynı olması isteniyorsa bu kullanım tavsiye edilmektedir. Bu yeteneğin kullanılması için config-server ayağa kaldırılırken environment'ların önüne 'SPRING_CLOUD_CONFIG_SERVER_OVERRIDES_' ön ekinin eklenmesi gerekmektedir.

Uygulamalarda config-server bağlantısı bootstrap.yml üzerinden sağlanmaktadır.

spring:
  config:
    import:
      - optional:configserver:${spring.cloud.config.uri}
  cloud:
    config:
      uri: ${SERVER_CONFIGURATION_REMOTE_URL:http://localhost:8888/config}
      profile: ${SERVER_CONFIGURATION_CLOUD_PROFILE:cloud-eureka,cloud-sleuth,hvl-context,hvl-data,hvl-logger,hvl-mail,hvl-security,hvl-service,hvl-session,database-datasource,instance,kafka,management,swagger,apm}
      label: ${SERVER_CONFIGURATION_LABEL:framework(_)spring}
      enabled: ${SERVER_CONFIGURATION_REMOTE_ENABLED:true}
      username: ${CONFIG_AUTH_USERNAME:admin}
      password: ${CONFIG_AUTH_PASSWORD:123456}

  logging:
    auth:
      username: ${LOGGING_AUTH_USERNAME:${spring.cloud.config.username}}
      password: ${LOGGING_AUTH_PASSWORD:${spring.cloud.config.password}}
    config: ${LOGGING_CONFIG:${spring.cloud.config.uri}/${spring.application.name}/default/framework(_)log4j2(_)instance(_)oauth/log4j2.yml}

Altyapı olarak loglama ve genel bütün konfigurasyonlarımız config-server üzerinden almaktayız. Burada profile mantığı kullanılarak parçalama yapılmıştır. Konfgiurasyon dosyalarını ve config-server dosyalarını https://gobitbucket.havelsan.com.tr/scm/javalt/hvl-infra.git adresinden inceleyebilirsiniz.


Eureka Web Starter #

Mikro servis mimaride dağıtık servisler hakkında bilgi almak için service-registry olarak Eureka kullanılmasına destek sağlamaktadır. Eureka entegrasyonu için gerekli temel yapıları sağlamaktadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-cloud-eureka.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cloud', name: 'hvl-cloud-eureka-web-starter'


Kubernetes Web Starter #

Mikro servis mimaride dağıtık servisler hakkında bilgi almak için service-registry olarak Kubernetes kullanılmasına destek sağlamaktadır. Kubernetes entegrasyonu için gerekli temel yapıları sağlamaktadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-cloud-kubernetes.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cloud', name: 'hvl-cloud-kubernetes-web-starter'


Service #

Mikro servis yapılarda uygulamaların birbirlerine declarative yapıda istek (Http request) atabilmesini sağlamaktadır. Yani geliştirici istek atacağı interface'i tanımladıktan sonra java üzerinden implementasyon yapmadan istek atabilmektedir. Burada teknoloji olarak OpenFeign kullanılmaktadır.

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "", url = "", path = "")
public interface SampleRestService {

    @GetMapping(path = "/sample", produces = MediaType.APPLICATION_JSON_VALUE)
    String sample();

}

Declarative yapıları injection yapmadan faydalanabilmek için HvlFeignClientBuilder sınıfını kullanabilirsiniz.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tr.com.havelsan.javarch.cloud.service.builder.HvlFeignClientBuilder;
import tr.com.havelsan.javarch.samples.jpa.data.logic.SampleRestService;

/**
 * @author javarch
 */
@SpringBootApplication
public class HvlSampleApplication {


    public static void main(String[] args) {
        SpringApplication.run(new Class[]{HvlSampleApplication.class}, args);

        final SampleRestService sampleRestService = HvlFeignClientBuilder.create().target(SampleRestService.class);

    }

}

FeignClient sınıflarının decoder, encoder, interceptor, logger alanlarını da konfigure edebilirsiniz. Altyapı decoder işlemi için HvlDecoder interfaceden türeyen HvlFeignClientDecoder, HvlFeignClientErrorDecoder, HvlFeignResponseDecoder sınıfları ile destek sağlamaktadır.
Altyapı encoder işlemi için HvlFeignEncoder sınıfı ile destek sağlamaktadır. Altyapı interceptor işlemi için HvlCloudServiceRequestInterceptor sınıfı ile destek sağlamaktadır. Altyapı logger işlemi için HvlFeignClientLogger sınıfı ile destek sağlamaktadır.

NOT: Yukarıda sağlanan desteklerin kullanımı zorunlu değildir. Uygulamaya göre özelleştirilebilir hatta arttırılabilir. FeignClient özelinde bile yazılabilir. Fakat burada özelleştirme yapılırken altyapının sağladığı destekler incelenmeli ve isteğin yaşam döngüsü bozulmamalıdır.

Http isteği için FeignClient declarative yapısının kullanılmasının en büyük problemi mikro servis mimaride uygulamalar dağıtık mimaride farklı JVM de çalıştığı için hatanın ele alınmasıdır. Altyapıda FeignClient kullanımında istek sonucunda hatayı JVM'de ele alınması sağlanmıştır. Bunun için FeignClient ** uçlarında kullanılacak hataların **HvlFeignClientError annotation'ı ile işaretlenmesi gerekmektedir.

import org.springframework.http.HttpStatus;
import tr.com.havelsan.javarch.cloud.service.annotation.HvlFeignClientError;
import tr.com.havelsan.javarch.exception.HvlCheckedException;
import tr.com.havelsan.javarch.exception.model.HvlErrorDetail;
import tr.com.havelsan.javarch.service.annotation.HvlExceptionHttpStatus;

@HvlFeignClientError
@HvlExceptionHttpStatus(code = HttpStatus.BAD_REQUEST)
public class SampleInvalidRequestException extends HvlCheckedException {

    public static final String ERROR_CODE = "code";

    public static final String ERROR_MESSAGE = "message";

    public SampleInvalidRequestException() {
        super(ERROR_MESSAGE, new HvlErrorDetail(ERROR_CODE, ERROR_MESSAGE));
    }

    public SampleInvalidRequestException(HvlErrorDetail errorDetail) {
        super(errorDetail);
    }

}

NOT: FeignClient hatalarının sistem tarafından taranması gerekmektedir. ' hvl.core.service.cloud.feign.client.exception.scan-path' özelliğine hatanın bulunduğu package verilmesi gerekmektedir.

ÖNERİ: FeignClient kullanımlarında arayüz sınıflarında @Validated ve @Valid annotationları kullanılmalıdır. Arayüz içerisindeki metotlarada gerekli validasyon annotationları konulmalıdır. Böylece istek atılmadan validasyondan geri döner.

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;

import javax.validation.constraints.NotEmpty;

@FeignClient(name = "", url = "", path = "")
@Validated
public interface SampleRestService {

    @GetMapping(path = "/sample", produces = MediaType.APPLICATION_JSON_VALUE)
    String sample(@NotEmpty String plainText);

}

drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-service.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cloud', name: 'hvl-cloud-service'


Session#

Uygulama içerisinde istek yaşam döngüsünde session bilgisinin taşınmasını ve kullanılmasını sağlayan altyapı bileşenidir. Bu altyapı bileşeni ihtiyaçlar doğrultusunda genişletilebilmektedir.


Context #

Uygulamada isteğin yaşam döngüsü boyunca Session bilgisi burada tutulmaktadır. HvlSession sınıfı ile tutulmaktadır.

İki şekilde kullanılabilmektedir:

  • DI (Dependency Injection) ile kullanılabilir.
import org.springframework.stereotype.Service;
import tr.com.havelsan.javarch.session.common.model.HvlSession;
import tr.com.havelsan.javarch.session.context.HvlSessionContext;

@Service
public class SampleService {

    private final HvlSessionContext sessionContext;

    public SampleService(HvlSessionContext sessionContext) {
        this.sessionContext = sessionContext;
    }

    public void test() {
        final HvlSession session = sessionContext.currentSession();
    }

}
  • Bean olmayan sınıflar statik olarak 'Holder' üzerinden kullanılabilir.
import tr.com.havelsan.javarch.session.common.model.HvlSession;
import tr.com.havelsan.javarch.session.context.HvlSessionContextHolder;

import java.util.Objects;

public final class SampleService {

    public static SampleService INSTANCE;

    public static SampleService getInstance() {
        if (Objects.isNull(INSTANCE)) {
            INSTANCE = new SampleService();
        }
        return INSTANCE;
    }

    public static void test() {
        final HvlSession session = HvlSessionContextHolder.currentSession();
    }

}

Uygulamada header ve cookie'den alınan bilgiler HvlSessionContextFilter sınıfında ayrıştırılarak * HvlSession* sınıfı ile session bilgisi tutulmaktadır.

NOT: HvlSession sınıfı içerisinde 'attributeMap' alanı bulunmaktadır. Yani istenildiği zaman session genişletilebilir.

Session genişletilmesinin 2 yöntemi bulunmaktadır:

  • HvlSessionContextManagerImpl sınıfını extend ederek değiştirilmek istenen metotlar değiştirilebilir.
  • HvlSessionContextFilter filtesi yerine uygulamaya özgü filtre yazılabilir. Bu filtre sonrasında çalıştırılarak * 'attributeMap'* alanına ekleme yapılabilir.

drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-session.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.session', name: 'hvl-session-context'


Security#

Uygulama içerisinde istek yaşam döngüsünde güvenlik ile ilgili bilgilerin taşınmasını ve kontrolünün yapılmasını sağlayan altyapı bileşenidir. Bu altyapı bileşeni ihtiyaçlar doğrultusunda genişletilebilmektedir.

ÖNERİ: @PreAuthorize gibi annotationlar RestController üzerine konulması tavsiye edilmektedir. Servise yetkisi olan kişi RestController'dan geçtikten sonra güvenliğe takılmamalıdır. Karmaşık yetki havuzlarının oluşmasını önlemektedir.


JWT #

CSRF (Cross Site Request Forgery) saldırılarını önlemek amacı ile kullanılmaktadır. Yani dışarıdan gelen isteklerin authentication (kimlik doğrulama) kısmından geçmiş olduğunu teyit etmek içindir. Altyapıda authentication ile ilgili veriler HVL_SESSION_ID ve HVL_TOKEN alanları ile taşınmaktadır. (Daha detaylı bilgi için: https://jwt.io/)

NOT: HVL_TOKEN değişkeni application-hvl-security.yml alanı içerisinde **'hvl.core.security.jwt.header.token' ** alanından değiştirilebilir. Değiştirilmesi durumunda alana bağlı durumlarda düzenlenmelidir.

JWT üretmek için HvlJwtGeneratorBuilder sınıfı kullanılmaktadır. JWT üretirken şifreleme imzası ( signature) önem taşımaktadır. HvlJwtAlgorithm sınıfı ile şifreleme algoritması seçilmektedir.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tr.com.havelsan.javarch.jwt.generator.builder.HvlJwtGeneratorBuilder;
import tr.com.havelsan.javarch.jwt.parser.algorithm.HvlRS256Algorithm;
import tr.com.havelsan.javarch.jwt.parser.model.HvlRSKeyPair;

/**
 * @author javarch
 */
@SpringBootApplication
public class HvlJpaServerApplication {


    public static void main(String[] args) {
        SpringApplication.run(new Class[]{HvlJpaServerApplication.class}, args);

        HvlJwtGeneratorBuilder.create()
                .setAlgorithm(new HvlRS256Algorithm(new HvlRSKeyPair()))
                .build();
    }

}

JWT içerisine konulan bilgiyi ayrıştırmak (parse) için HvlJwtParserBuilder sınıfı kullanılmaktadır. Burada önemli olan üretim yapılan algoritma ile ayrıştırma yapılan algoritmanın türünü aynı olması gerekmektedir. (HvlJwtAlgorithm aynı olmalıdır.)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tr.com.havelsan.javarch.jwt.parser.algorithm.HvlRS256Algorithm;
import tr.com.havelsan.javarch.jwt.parser.builder.HvlJwtParserBuilder;
import tr.com.havelsan.javarch.jwt.parser.model.HvlRSKeyPair;

/**
 * @author javarch
 */
@SpringBootApplication
public class HvlJpaServerApplication {


    public static void main(String[] args) {
        SpringApplication.run(new Class[]{HvlJpaServerApplication.class}, args);

        HvlJwtParserBuilder.create()
                .setAlgorithm(new HvlRS256Algorithm(new HvlRSKeyPair()))
                .build();
    }

}

NOT: Altyapıda JWT üretimi için varsayılan olarak HvlRS256Algorithm algoritması kullanılmaktadır. ( hvl.core.security.jwt.key-provider.algorithm) RSA algoritmasının kullanılabilmesi için private ve public key olması gerekmektedir. Altyapıda varsayılan olarak hvl.pem ve hvl.public.pem dosyaları bulunmaktadır. Bu dosyalar ' hvl.core.security.jwt.key-provider.file.public-file-path' ve ' hvl.core.security.jwt.key-provider.file.private-file-path' alanları ile değiştirilebilmektedir.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-security.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.security', name: 'hvl-jwt-generator'
    group: 'tr.com.havelsan.framework.security', name: 'hvl-jwt-parser'
    group: 'tr.com.havelsan.framework.security', name: 'hvl-jwt-security'


Session Provider #

Sisteme giriş yapmış (authenticate) bir istemcinin her bir isteğinde herhangi bir uygulama (Örneğin session-server) ile kimlik doğrulaması yapabileceği arayüz sunulmaktadır. HvlSecuritySessionProvider sınıfını implement edilerek oturum veya istek bilgileri güvenlik katmanına özelleştirilerek aktarılabilir.

NOT: Mikro servis mimarilerde uygulamalar stateless olduğu için sisteme giriş yapan kullanıcıların oturum bilgileri bir sistemde tutulması gerekmektedir. HvlSecuritySessionProvider sınıfından implement edilerek herhangi bir uygulama ile entegre olunabilir.


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.security', name: 'hvl-security-session-provider'


Context #

Uygulama güvenlik ile ilgili verilere ulaşmamızı sağlamaktadır.

İki şekilde kullanılabilmektedir:

  • DI (Dependency Injection) ile kullanılabilir.
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import tr.com.havelsan.javarch.security.common.model.HvlAuthenticationToken;
import tr.com.havelsan.javarch.security.context.HvlSecurityContext;

import java.util.Collection;

@Service
public class SampleService {

    private final HvlSecurityContext securityContext;

    public SampleService(HvlSecurityContext securityContext) {
        this.securityContext = securityContext;
    }

    public void test() {
        final HvlAuthenticationToken authentication = securityContext.getAuthentication();
        final Collection<GrantedAuthority> authorities = authentication.getAuthorities();
    }

}
  • Bean olmayan sınıflar statik olarak 'Holder' üzerinden kullanılabilir.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tr.com.havelsan.javarch.security.common.model.HvlAuthenticationToken;
import tr.com.havelsan.javarch.security.context.HvlSecurityContextHolder;

/**
 * @author javarch
 */
@SpringBootApplication
public class HvlJpaServerApplication {


    public static void main(String[] args) {
        SpringApplication.run(new Class[]{HvlJpaServerApplication.class}, args);

        final HvlAuthenticationToken authentication = HvlSecurityContextHolder.getAuthentication();
    }

}

NOT: Hiyerarşik yetki desteği sağlanmaktadır. // TODO hiyerarşik yetki desteği eklenince separator ile açıklanmalı.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-security.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.security', name: 'hvl-security-context'


Web Starter #

Altyapının thymeleaf ile geliştirdiği giriş ekranını sağlamaktadır. Uygulamalarda kullanılarak login işlemi gerçekleştirilebilir.

@Bean
@ConditionalOnMissingBean
AuthenticationProvider authenticationProvider(HvlWebSecurityProperties webSecurityProperties){
        return new HvlWebSecurityInmemoryAuthenticationProvider(webSecurityProperties);
        }

Sağlanan altyapı ekranı ile herhangi bir sisteme entegre olmak istenirse yukarıdaki Bean ezilmesi yeterli olacaktır. Varsayılan olarak immemory çalışmaktadır. Kullanıcı bilgileride 'application-hvl-web-security.yml' içeisinden tanımlanmaktadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-web-security.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.security', name: 'hvl-security-web-starter'


Cloud Security#

Security paketinin cloud yapısına uygun entegre edilmesi ile oluşan altyapı bileşenidir. Bu altyapı bileşeni ihtiyaçlar doğrultusunda genişletilebilmektedir.


JWT Session Provider #

HvlSecuritySessionProvider sınıfının cloud entegrasyonunu sağlamaktadır. HvlCloudJwtSessionProviderImpl implementasyonu ile kimlik doğrulama yapılacak uygulama ile entegre olmaktadır.

NOT: Altyapıda varsayılan olarak KEYSIS ürünü ile entegre olmaktadır.


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-hvl-security.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cloud.security', name: 'hvl-cloud-jwt-session-provider'


Session Provider #

Güvenlik katmanında kimlik doğrulama işlemi için entegrasyon arayüzü sağlanmaktadır. Güvenlik katmanı ile entegre olacak uygulamının bu arayüze uygun servis ucu açması gerekmektedir.

NOT: KEYSIS ürününde 'session-server' kimilk yönetimi için entegre durumdadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-hvl-security.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cloud.security', name: 'hvl-cloud-security-session-provider'


Cache#

Uygulamalarda in-memory ve distributed cache yeteneklerini sağlayan altyapı bileşenidir. Caffeine cache ve redis cache destekleri sağlanmaktadır. Bu altyapı bileşeni ihtiyaçlar doğrultusunda genişletilebilmektedir.

ÖNERİ: Cache kullanımı DTO üzerinden yapılması tavsiye edilmektedir. Gereksiz ve çok değişecek veriler cache'e konulmamalıdır.


Core #

Uygulamada cache yönetimi için HvlCacheManager sınıfı sunulmaktadır. Böylece uygulama içerisinde annotion dışında cache yönetimi yapılmaktadır.

NOT: hvl-cache-core kullanılan sağlayıcıya göre entegrasyon göstermektedir. (Redis, ECache, Caffeine vb...)


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cache', name: 'hvl-cache-core'


Redis #

Java dünyasında Redis ile entegrasyon için kullanılan en popüler teknolojiler jedis ve lettuce'dur. Altyapı olarak bu iki teknolojiye de destek verilmektedir.


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cache', name: 'hvl-redis'

drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-redis.yml' dosyasıyla konfigure edilebilmektedir.



Caffeine #

Altyapı, in memory olarak çalışan caffeine cache desteği sağlamaktadır. In memory cache kullanımları için performansından dolayı önerilir.


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.cache', name: 'hvl-caffeine'

drawing Nasıl konfigüre edilir?
spring:
  cache:
    type: caffeine


Data#

Uygulamalarda veri katmanında kullanılacak fonksiyonalitelerin sağlandığı altyapı bileşenidir. ORM işlemleri için JPA ve QueryDSL teknolojileri tercih edilip bu teknolojiler üzerinde özelleştirmeler yapılmıştır. Auditing altyapısı için Javers ve Envers teknolojilerine destek verilmektedir. Aynı zamanda sorgulama, view, auditing için özelleştirilmiş yetenekler sağlamaktadır.


Liquibase #

Liquibase veritabanı şeması üzerindeki değişikliklerimizi yönetmemizi sağlayan açık kaynaklı bir Java kütüphanesidir. Veritabanı şeması üzerindeki değişikliklerin izlenmesini, yönetilmesini ve uygulanmasını sağlar. Kaba tabirle veritabanı üzerinde versiyon kontrol sistemi kurmamıza yardımcı olur.

Preliquibase ise liquibase scriptlerinden önce çalışarak gerekli veritabanı şemasını oluşturmaktadır.


drawing Nasıl konfigüre edilir?

hvl-infra altında bulunan 'application-database-datasource.yml' dosyasıyla konfigure edilebilmektedir.

Konfigürasyonları spring.liquibase ve preliquibase altında bulunmaktadır.

spring:
  liquibase:
    default-schema: ${spring.jpa.properties.hibernate.default_schema}
    change-log: ${LIQUIBASE_CHANGE_LOG:db/changelog-root.yaml}
    enabled: ${LIQUIBASE_ENABLED:false}
    drop-first: ${LIQUIBASE_DROP_FIRST:false}
    url: ${LIQUIBASE_DB_URL:${spring.datasource.url}}
    user: ${LIQUIBASE_DB_USER:${spring.datasource.username}}
    password: ${LIQUIBASE_DB_PASSWORD:${spring.datasource.password}}
    clear-checksums: ${LIQUIBASE_CLEAR_CHECKSUMS:false}
    contexts: ${LIQUIBASE_CONTEXTS:dev}
preliquibase:
  default-schema: ${spring.liquibase.default-schema}
  sqlScriptReferences: classpath:/db/preliquibase/schema.sql
  dbPlatformCode: postgresql
  • default-schema: Liquibase scriptleri çalıştırırken şema verilmemiş scriptlerde kullanıacak varsayılan veritabanı şema bilgisidir.
  • change-log: Liquibase scriptleri çalıştırırken ilk olarak bakacağı change-log dosyasıdır. Bu dosyanın içerisindeki bilgilere göre sırası ile scriptler çalıştırılmaktadır.
  • enabled: Uygulama ayağa kalkarken liquibase'in devreye girip girmeyeceğini yöneten konfigürasyon bilgisidir.
  • drop-first: Uygulama ayağa kalkarken liquibase'in tüm tabloları temizleyip herşeyi en baştan çalıştırmasını sağlayan konfigürasyon bilgisidir.
  • url: Liquibase'in scriptlerini çalıştıracağı veritabanı url bilgisidir.
  • user: Liquibase'in scriptlerini çalıştıracağı veritabanının kullanıcı adı bilgisidir.
  • password: Liquibase'in scriptlerini çalıştıracağı veritabanının şifre bilgisidir.
  • clear-checksums: Liquibase'in scriptlerinde değişiklik olduğu durumda güncel scriptlerin baz alınacağını belirleyen konfigürasyon bilgisidir. Normal koşullarda liquibase çalıştırdığı bir script değişmişse hata vererek uygulamayı kapatır. Bu konfigürasyon true olduğu durumlarda mevcut checksum ı günceller ve hata atmadan devam eder.

    NOT: Canlı ortamlarda kurulum yapılmışsa çalışmış scriptleri güncellemek son derece tehlikelidir.
  • contexts: Liquibase'in scriptlerini çalıştırırken kullanacağı context bilgisidir. Context ile belirtilmiş changeset leri bu konfigürasyon kapsamında çalıştıracaktır. Virgül kullanılarak birden fazla değer verilebilir.

Preliquibase:

  • default-schema: Şemanın olmadığı durumlarda preliquibase tarafından oluşturulacak şema bilgisidir.
  • sqlScriptReferences: Şema oluşturulması için çalışacak script dosyasının path bilgisidir.
  • dbPlatformCode: Veri tabanı platform bilgisidir. Varsayılan olarak postgresql olarak ayarlanmıştır.


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-liquibase-initializer'

Proje içerisinden örnek liquibase kullanım yapısı aşağıdaki gibidir.


Converter #

Hibernate, JPA teknolojilerine bağlı olmadan nesneler arası dönüştürücüleri sağlanmaktadır. Aynı zamanda enum sınıfların ordinal dışında veritabanı işlemleri için dönüştürücüsünü sağlamaktadır.

NOT: HvlGenericConverter ve HvlGenericHibernateConverter sınıfları runtime anında reflection ile çalıştığı için performansal olarak önerilmemektedir. HvlGenericHibernateConverter dönüştürücüsü hibernate annotation'larına göre davranış göstermektedir. Herhangi bir veritabanı bağlılığı gerekmemektedir.


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-converter'


JPA #

Veritabanı işlemlerini sağlayan altyapı bileşenidir. Veritabanı işlemlerini yapacağımız sınıflar declarative olarak sağlanmaktadır.

Hibernate enhancement plugin desteğimiz ile varsayılan olarak 'dynamic update' aktif sunulmaktadır. Eğer sınıfta 'dynamic update' çalışması istenmiyorsa HvlDynamicUpdateExclude annotation kullanılmalıdır.

NOT: 'dynamic update' performans için önemlidir. Varitabanı işlemlerinde 'update' işleminde sadece değişen alanların gönderilmesini sağlamaktadır.

JPA kullanırken transaction kullanımı önemlidir. Transaction için Transactional annotation'ını kullanılmaktadır. * Transactional* annotation'ını unchecked exception'larda direk rollback almaktadır. Fakat checked işlemleri için geliştiricinin bu durumu ele alması beklenmektedir. Altyapıda bütün checked hatalar için rollback aktif olması için * HvlTransactionalRollbackForCheckedException* annotation'ı bulunmaktadır.

Altyapıda veritabanı işlemlerinde kolon bazlı şifreleme yeteneği bulunmaktadır. Convert annotation'ı ile kullanılmaktadır.

import javax.persistence.Convert;

@Convert(converter = HvlStringCryptoConverter.class)

NOT: Kolon şifreleme aktif etmek için 'application-database-datasource.yml' içerisinde ' spring.jpa.properties.hibernate.encryption_enabled' alanının 'true' yapılması gerekmektedir. Altyapı olarak şifreleme algoritması olarak şu anda AES desteklenmektedir. AES üzerinden şifreleme işleminde kullanılacak olan 'key değeri 'spring.jpa.properties.hibernate.encryption_key' alanından verilmesi gerekmektedir.

Altyapı kullanılarak yapılan veritabanı işlemlerinde kimin yaptığı gibi işlem sırasında otomatik verilmesi gereken değerler HvlJpaAwareProvider sınıfı ile yönetilmektedir. Geliştiriciler tarafında özelleştirilebilir.

JPA ile ilgili içeriğe ulaşmak için HvlJpaContext veya HvlJpaContextHolder sınıfı kullanılmalıdır.

Veritabanı işlemleri için altyapıdan PostgreSQL ve Oracle veritabanları için dialect bulunmaktadır. Bu dialect'ler özelleştirilmiştir. Örneğin; PostgreSQL için ilike vb. fonksiyonlar eklenmiştir.

NOT: Dialect 'application-database-datasource.yml' içerisinde ' spring.jpa.properties.hibernate.dialect' alanınından yönetilmektedir. Kullanılmak istenen dialect paket bilgisi ile verilmelidir. 'tr.com.havelsan.javarch.data.jpa.dialect.oracle.HvlOracleSQL12cDialect' ve ' tr.com.havelsan.javarch.data.jpa.dialect.postgresql.HvlPostgreSQL10Dialect' altyapıdan sağlanan dialect'lerdir.

Altyapının sağladığı declarative repository sınıflarını kullanabilmek için konfigurasyon sınıfınıza aşağıdaki annotation eklenmelidir.

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import tr.com.havelsan.javarch.data.jpa.factory.HvlJpaRepositoryFactoryBean;

@EnableJpaRepositories(basePackages = {"base_package"},
        repositoryFactoryBeanClass = HvlJpaRepositoryFactoryBean.class)

Veritabanı sorguları için Querydsl teknolojisi kullanılmaktadır. Altyapıya özgü alanların varsayılan değerlerinin verildiği ve sorgu (predicate) oluşturmaya yarayan HvlBaseQueryGenerator sınıfından türeyen * HvlEntityQueryGenerator* ve HvlViewQueryGenerator sınıfı bulunmaktadır.

NOT: Sorgulama işlemi için bu sınıflardan türeyen sınıfları kullanmak önerilmektedir. 'Soft delete' gibi özel yapılar için yapılan değişiklikler desteklenmektedir. Geliştiricinin ekstra kontrol veya ekleme yapmasına gerek yoktur.

Veritabanı işlemleri için altyapı tarafından 4 tane arayüz sağlanmaktadır:

  • HvlJpaRepository: 'HvlEntity' sınıfından türeyen sınıflar için kullanılan arayüzdür.
  • HvlJpaSearchRepository: Sorgulama ile ilgili fonksiyonların sağlandığı arayüzdür.
  • HvlJpaSimpleRepository: 'HvlSimpleEntity' sınıfından türeyen sınıflar için kullanılan arayüzdür.
  • HvlJpaViewRepository: 'HvlView' annotation'a sahip entity sınıfları için persist yeteneklerinin bulunmadığı arayüzdür.

drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, application-hvl-data.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa'


Envers #

Veritabanı işlemlerinin izini tutmak için Envers teknolojisi kullanılmaktadır. Envers nesnenin üzerinde yapılan işlemleri nesnenin tablo isminin sonuna '_AUD' eklediği tablo üzerinde tutmaktadır.

Altyapıdan gelen declarative repository kullanımı için aşağıdaki konfigurasyon eklenmelidir.

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import tr.com.havelsan.javarch.data.jpa.envers.factory.HvlEnversJpaRepositoryFactoryBean;

@EnableJpaRepositories(basePackages = {"base_package"},
        repositoryFactoryBeanClass = HvlEnversJpaRepositoryFactoryBean.class)

drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, application-hvl-data.yml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-envers'
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-envers-redis-service'
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-envers-service'


Session Aware #


drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-session-aware-configuration'


Redis Second Level Cache #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


LDAP #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


Redis #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


Domain Model #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


DTO Model #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


Hibernate Annotations #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


Initializer #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


Model Converter #


drawing Nasıl konfigure edilir ?

hvl-infra altında bulunan 'application-database-datasource.yml, redisson-slc.yaml' dosyasıyla konfigure edilebilmektedir.



drawing Uygulamaya nasıl eklenir ?
    group: 'tr.com.havelsan.framework.data', name: 'hvl-data-jpa-slc-redis'


Message Broker#

Uygulamalarda message queue yapısını kullanmayı sağlayan altyapı bileşenidir. Kafka desteği sağlanmaktadır.

Kafka #

Kafka ile ilgili detaylı bilgiye ve hvl-kafka kullanımına Kafka sayfasından ulaşabilirsiniz.


Support#

Uygulama mimarisinde ihtiyaç duyulan destek paketlerini içeren altyapı bileşenidir.

- Elasticsearch Apm
- Spring Batch
- File System
- Mail Sender
- Micrometer Prometheus
- Multitenancy
- Sleuth