1.1. 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. Actuator, configuration, context, crypto, exception, initializer, service, swagger, util gibi 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 ve modellerin bilgilerinin dönülmesini sağlamaktadır. Bu bilgileri alabilmek için ilk olarak ip:port/actuator
adresine istek atılmalıdır.
Servis bilgilerinin alınabilmesi için aşağıdaki uçların kullanılması gerekmektedir.
Model bilgilerinin alınabilmesi için aşağıdaki uçların kullanılması gerekmektedir.
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.
hvl-infra altında bulunan 'application-management.yml' dosyasıyla konfigure edilebilmektedir.
Actuator Environment Gizleyici#
/actuator/env
pathi üzerinden görüntülenen, uygulamanın kullandığı ortam değişkenlerinde, şifre bilgileri gibi görünmesi istenmeyen kritik bilgi olabilir. Bu bilgileri gizlemek için EKSEN tarafından sağlanan konfigürasyonlar kullanılabilir. application-management.yml
dosyasından sağlanan konfigürasyon bilgileri aşağıdaki gibidir.
hvl:
management:
endpoint:
env:
sanitizer:
key-regexes:
- .*[Pp]assword$
- .*[Ss]ecret$
- hvl.core.security.web.credentials
hvl.management.endpoint.env.sanitizer.key-regexes: Gizlenmek istenen uygulama konfigürasyonlarının regex olarak key bilgisidir. Varsayilan olarak password
ve secret
kelimeleri ilen biten key'leri gizlemektedir.
Örnek Çıktı:
"spring.datasource.url": {
"value": "jdbc:postgresql://hvlpostgresmultipledatabases:5432/hvl",
"origin": "Config Server file:/var/lib/config-server/framework/spring/application-database-datasource.yml:14:10"
},
"spring.datasource.username": {
"value": "hvl",
"origin": "Config Server file:/var/lib/config-server/framework/spring/application-database-datasource.yml:15:15"
},
"spring.datasource.password": {
"value": "******",
"origin": "Config Server file:/var/lib/config-server/framework/spring/application-database-datasource.yml:16:15"
},
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 tarama işlemlerinde sadece konfigurasyon taranması için ayraç olarak kullanılabilmektedir.
Profile bağlı tarama yapabilmek için sağlanan HvlProfileComponentScanFilter
sınıfı bulunmaktadır. Bu sınıf kullanılarak sadece @Profile
içeren konfigürasyon sınıfları taranabilmektedir.
@Configuration
@ComponentScan(basePackages = {HvlLogServerConfigurationConstant.BASE_PACKAGE},
useDefaultFilters = false,
includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM, value = HvlProfileComponentScanFilter.class),
}
)
public class HvlLogServerConfiguration extends HvlBaseConfiguration {
}
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.
Konfigurasyonları jasypt kütüphanesi ile şifreleme yeteneği bulunmaktadır. Şifreleme yeteneği sağlanan algoritma türleri: HvlConfigurationEncryptorType
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.
hvl-infra altında bulunan 'application-instance.yml' dosyasıyla konfigure edilebilmektedir.
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şmayı sağlamaktadır.
2 ş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 mekanizmasına destek sağlamaktadır. Bunun için HvlApplicationEventListener
ve HvlApplicationEventPublisher
sınıfları kullanılmaktadır.
hvl-infra altında bulunan 'application-hvl-context.yml' dosyasıyla konfigure edilebilmektedir.
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("mySecretKey").build();
final String encryptText = aesCryptoService.encrypt("test");
final String decryptText = aesCryptoService.decrypt(encryptText);
}
}
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ı vasıtası ile bilgi dönülmektedir.
Initializer#
Uygulamaya ilklendirme özelliği kazandırmaktadır. İlklendirme belirli bir path üzerindeki script dosyaları ile yapılabildiği gibi aynı zamanda git üzerinden de script dosyalarını okuyup ilklendirme yapılabilmeyi sağlamaktadır.
hvl-infra altında bulunan 'application-hvl-data.yml' dosyasıyla konfigure edilebilmektedir.
Bağımlılık eklendikten sonra git ilklendirmesi için HvlInitializerGitProperties
sınıfından extend edip propertyler bağlanarak kullanıma hazır hale getirilebilir.
@ConfigurationProperties(prefix = HvlEnableRToolConfigurationConstant.REPORT_INITIALIZER_PROPERTIES_PREFIX)
public class HvlRToolReportInitializerGitProperties extends HvlInitializerGitProperties {
}
Git kullanmadan yalnızca path üzerinden ilklendirme özelliği kazandırılmak isteniyorsa aşağıdaki örnekteki gibi HvlInitializerProperties
sınıfı exten edilip propertyler bağlanabilir.
@ConfigurationProperties(prefix = HvlEnableRToolConfigurationConstant.REPORT_INITIALIZER_PROPERTIES_PREFIX)
public class HvlRToolReportInitializerProperties extends HvlInitializerProperties {
}
Sonrasında aşağıdaki gibi HvlInitializerGitServiceImpl
sınıfından extend eden bir ilklendirme komponenti ile ilklendirme süreci tamamlanabilir.
@Component
@ConditionalOnProperty(
prefix = HvlEnableRToolConfigurationConstant.REPORT_INITIALIZER_PROPERTIES_PREFIX,
name = HvlRToolReportInitializerProperties.ENABLED_PROPERTY_NAME,
havingValue = BooleanUtils.TRUE
)
public class HvlRToolReportInitializer
extends HvlInitializerGitServiceImpl implements InitializingBean {
private final HvlRToolReportInitializerProperties reportInitializerProperties;
private final HvlRToolBatchedReportImportProcessor batchedReportImportProcessor;
public HvlRToolReportInitializer(
HvlRToolReportInitializerGitProperties reportInitializerGitProperties,
HvlRToolReportInitializerProperties reportInitializerProperties,
HvlRToolBatchedReportImportProcessor batchedReportImportProcessor) {
super(reportInitializerGitProperties);
this.reportInitializerProperties = reportInitializerProperties;
this.batchedReportImportProcessor = batchedReportImportProcessor;
}
/**
* {@inheritDoc}
*/
@Override
public void afterPropertiesSet() throws Exception {
initialize();
}
/**
* {@inheritDoc}
*/
@Override
protected void doInit(String path) {
final Path batchedReportImportFilePath = Path.of(path)
.resolve(this.reportInitializerProperties.getBatchedReportImportFilePath());
batchedReportImportProcessor.importReportTemplatesFrom(batchedReportImportFilePath)
.block();
}
}
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 HvlResponseEntity
sınıfları bulunmaktadır. Bu sınıflar sayesinde payload, header, errorDetail gibi alanlar istemciye standart olarak dönülmektedir. HvlResponseEntity
objelerin byte array gibi yapılarda geriye dönülmesinin istendiği durumlarda kullanılmaktadır.
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. Bu yetenek @HvlExceptionHttpStatus
anotasyonu ile sağlanmaktadı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 filtrelenip 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 metotlara da gerekli validasyon annotationları konulmalıdır. Böylece metot içerisindeki iş mantığı çalışmadan ve kaynak tüketmeden önce 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);
}
hvl-infra altında bulunan 'application-hvl-service.yml' dosyasıyla konfigure edilebilmektedir.
Request Loglama#
Eksen, backend uygulamasına gelen isteklerin kafka, fluentd, elasticsearch pipeline'ı ile depolanmasını sağlar.
Bunu yaparken aşağıdaki başlıca istatistikler toplanabilir:
- İsteğin UI üzerinde hangi ekrandan geldiği
- İsteğin gerçekleşme süresi
- Ip adresi
- Backend uygulamasının jvm istatistikleri
- Oturumdaki kullanıcı adı
- Thread bilgileri
Konfigürasyonlar yapılarak toplanan bilgiler arttırılabilir, bu durumda performans kayıpları göz önünde bulundurulmalıdır.
application-hvl-service.yml
içerisinden config-server vasıtasıyla varsayılan olarak gelen ayarlar aşağıdaki gibidir.
hvl:
request-logger:
enabled: ${REQUEST_LOGGER_ENABLED:false}
source-url-request-header: ${REQUEST_LOGGER_SOURCE_URL_HEADER:Hvl-Source-Request-Path}
logger-text: ${REQUEST_LOGGER_LOGGER_TEXT:log}
application-name: ${REQUEST_LOGGER_APP_NAME:eksen}
application-type: ${REQUEST_LOGGER_APP_TYPE:tomcat}
include-list: ${REQUEST_LOGGER_INCLUDE_LIST:""}
context-name: ${REQUEST_LOGGER_CONTEXT_NAME:""}
pool-name: ${REQUEST_LOGGER_POOL_NAME:eksen}
hvl.request-logger.enabled: Request loglamanın devreye girmesini sağlar.
hvl.request-logger.source-url-request-header: UI tarafından hangi ekranda işlem yapıldığının gönderildiği header bilgisidir.
hvl.request-logger.logger-text: Loglanan verilerdeki log ismidir.
hvl.request-logger.application-name: Loglanan verilerdeki uygulama adı bilgisidir.
hvl.request-logger.application-type: Loglanan verilerdeki uygulama tipi bilgisidir.
hvl.request-logger.include-list: Loglanacak sistemsel verileri loglama dahil etmek için kullanılır. Her bir değerin metrik toplamak için performans düşüreceği göz önünde bulundurulmalıdır. Alabileceği değerler: class, gc, memory, os, jvmProps, thread, hikari, env, tomcat, unix, disk
hvl.request-logger.context-name: Loglanan verilerdeki context adı bilgisidir.
hvl.request-logger.pool-name: Loglanan verilerdeki pool adı bilgisidir.
Loglanacak request'ler kafka üzerinden elasticsearch'e gönderildiği için uygulamanın log4j2.yml
dosyalarına aşağıdaki gibi eklemeler yapılmalıdır.
Appenders
altına Kafka
appender'i eklenmelidir.
Configuration:
appenders:
Kafka:
name: Kafka-true
topic: javalt-request-logs
syncSend: false
JsonLayout:
charset: UTF-8
properties: true
KeyValuePair:
- key: indexName
value: request-logs-\${spring:spring.application.name}
property:
- name: "bootstrap.servers"
value: \${spring:spring.kafka.bootstrap-servers}
Dikkat
Eğer uygulamanın herhangi bir veritabanı bağımlılığı yoksa aşağıdaki şekilde HibernateJpaAutoConfiguration
ve DataSourceAutoConfiguration
sınıfları exclude edilmelidir.
Uyarı
Kafka appender'i eklendiğinde uygulama kafka'ya bağımlı halecektir. Kafka appender kullanılmak istenmediği durumlarda loglar fluentd'ye farklı bir yöntem ile iletilmelidir.
Appender eklendikten sonra request loglarının kafkaya gönderilmesini sağlamak için loggers
altına aşağıdaki ekleme yapılmalıdır.
Loggers:
logger:
- name: log
level: info
additivity: false
AppenderRef:
- ref: Console
- ref: RollingFile
- ref: Kafka-\${spring:hvl.core.kafka.support.enabled}
Yukarıdaki örnekte name: log
kısmı önemlidir ve değiştirilmemelidir.
- Request loglaması yapılan sınıfta kullanılan logger name değeri
log
'dur. ref: Kafka-\${spring:hvl.core.kafka.support.enabled}
kısmı ise, yukarıda tanımladığımızKafka-true
appender'ının kullanılacağını gösterir. Böylece loglanacak request'ler kafka'ya yazılmış olacaktır. Uygulama konfigürasyonlarından gelenhvl.core.kafka.support.enabled
değerine göre kafkaya gönderim sağlanmaktadır. Bu değer false gelirse request logları kafkaya yazılmayacaktır.
Authorization için kullanılan log4j2 konfigürasyonuna buradan ulaşılabilir.
Yukarıdaki konfigürasyonlar yapıldıktan sonra Kafka appender içerisindeki topic'e loglar gönderilmeye başlayacaktır. hvl-infra
içerisindeki fluentd uygulaması, varsayılan olarak javalt-request-logs
topic'ini dinleyecek ve sonrasında elasticsearch'e gönderecek şekilde konfigüre edilmiştir. Kafka appender içerisindeki indexName
bilgisine göre elasticsearch üzerinde index oluşacaktır.
UI'dan gelen header bilgisi hvl.request-logger.source-url-request-header
alanındaki değer ile (varsayılan değer Hvl-Source-Request-Path
) eşleştiği takdirde, elasticsearch üzerinde contextMap.requestedClientUrl
alanına basılacaktır.
Kibana örneği aşağıdaki gibidir:
Uygulama Mesaj Context#
UI'dan atılan istekler sonucunda backend tarafında yapılan işlemlerin toplu bir şekilde HvlResponse
içerisinde dönülmesi sağlanmaktadır.
Örneğin; UI üzerinden rest ile A servisi çağırıldığını varsayalım, A servisi içerisinde yapılan işlemler için mesaj context'ine mesajlar eklendi ve rest ile B servisi çağırıldı. B servisi de aynı şekilde kendi işlemleri için mesaj context'ine mesajlarını ekledi. Bu işlemler sonucunda UI'a dönen HvlResponse
nesnesi içerisinde messageMap
alanında hem A hem de B servisinden eklenen mesajlar bulunacaktır.
Kullanım için EKSEN altyapısından sağlanan HvlWebMessageEmitter
sınıfı inject edilerek kullanılmalıdır.
Uyarı
HvlWebMessageEmitter sınıfı RequestScope
olarak çalışmaktadır.
Uyarı
HvlWebMessageEmitter'a eklenen mesajlar ve HvlResponse
arasındaki işlemler EKSEN tarafından sağlanan message converterlar ve feign decoder'lar üzerinden yapıldığı için, RestClient
veya RestTemplate
gibi yapılarla manuel istek atıldığı durumlarda message converter olarak HvlMappingJackson2HttpMessageConverter
kullanılmalıdır.
Aşağıdaki şekillerde mesaj context'ine ekleme yapılabilir.
webMessageEmitter.addMessages(Level.INFO, List.of("test message", "test message 2", "test message 3"));
webMessageEmitter.addMessage(Level.DEBUG, "test message debug 1");
webMessageEmitter.addMessage(Level.DEBUG, "test message debug 2");
webMessageEmitter.addMessage(Level.ERROR, "test error 1");
webMessageEmitter.addMessage(Level.ERROR, "custom_key", "test error with custom key");
Aşağıda örnek bir servis sınıfı bulunmaktadır.
/**
* @author javarch
*/
@Service
@HvlTransactionalRollbackForCheckedException
public class HvlBookServiceImpl implements HvlBookService {
private final HvlBookOperationalManager bookOperationalManager;
private final HvlBookManager bookManager;
private final HvlWebMessageEmitter webMessageEmitter;
public HvlBookServiceImpl(
HvlBookOperationalManager bookOperationalManager,
HvlBookManager bookManager,
HvlWebMessageEmitter webMessageEmitter) {
this.bookOperationalManager = bookOperationalManager;
this.bookManager = bookManager;
this.webMessageEmitter = webMessageEmitter;
}
/**
* {@inheritDoc}
*/
@Override
public void save(@NotNull @Valid HvlBookModel bookModel) {
bookOperationalManager.save(bookModel);
webMessageEmitter.addMessage(Level.INFO, "Kayıt eklendi.");
}
/**
* {@inheritDoc}
*/
@Override
@Validated(value = {HvlConstraintGroups.ModifyingOperation.class})
public void update(@NotNull @Valid HvlBookModel bookModel) {
bookOperationalManager.update(bookModel);
webMessageEmitter.addMessage(Level.INFO, "Kayıt güncellendi.");
}
/**
* {@inheritDoc}
*/
@Override
public void deleteByUuid(
@NotBlank
@Size(max = HvlPersistableDataConstraint.UUID_SIZE, min = HvlPersistableDataConstraint.UUID_SIZE) String uuid) {
bookOperationalManager.deleteByUuid(uuid);
webMessageEmitter.addMessage(Level.INFO, "Kayıt silindi.");
}
}
Swagger#
Uygulamaya swagger yeteneği kazandırmak için kullanılmaktadır. Cloud ve Boot için destek sağlanmaktadır.
hvl-infra altında bulunan 'application-swagger.yml' dosyasıyla konfigure edilebilmektedir.
Util#
Uygulama geliştirirken genel destek sınıfları sunulmaktadır. Destek sınıfları:
- Dil ve ortak kullanılacak sabitler için
HvlCommonConstant
,HvlLanguageConstant
- 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
NOT: EKSEN altyapısı kullanılan projelerde bu kütüphaneyi ayrıca sisteme dahil etmeye gerek yoktur. EKSEN altyapısı
hvl-util
kütüphanesini otomatik olarak sisteme dahil etmektedir.
Ayrıca hvl-util kütüphanesi projeye eklendiğinde aşağıdaki kütüphaneleri de sisteme otomatik olarak ekleyecektir. Bundan dolayı hvl-util
, EKSEN altyapısını kullanan projelerin aşağıdaki kütüphaneleri tekrar eklemesine gerek olmayacaktır.
commonsIOVersion=2.15.0
apacheCommonsCollections4Version=4.4
googleGuavaVersion=32.0.1-jre
api(
[group: 'commons-io', name: 'commons-io', version: commonsIOVersion],
[group: 'org.apache.commons', name: 'commons-collections4', version: apacheCommonsCollections4Version],
[group: 'org.apache.commons', name: 'commons-lang3'],
[group: 'com.google.guava', name: 'guava', version: googleGuavaVersion],
[group: 'commons-codec', name: 'commons-codec'],
[group: 'jakarta.servlet', name: 'jakarta.servlet-api'],
[group: 'org.apache.httpcomponents.client5', name: 'httpclient5'],
)