Changelog do Cloudsupport
Versão 1.14.0
- Atualizada assinatura de
PersistenceContext.findByAttr
: parâmetrovalue
agora aceita Object em vez de Serializable, para suporte a entidades como argumento - Corrigido
PageableQuery
quando o fetch inclui subpath - Corrigido
PersistenceContext.getFetchJoinClauses
quando o fetch inclui subpath
Versão 1.13.0
- Adicionado método
getSemanticLogginInCoreAttrs()
emSecurityUtils
que retorna um mapa com atributos primários do usuário autenticado:- Se JWT:
user.sub
,user.username
,user.name
,user.email
,user.user_id
,user.account_id
,user.department_id
- Para outros auth tokens do Spring Security:
user.principal
- Se JWT:
- Adicioando filtro web no Spring Security para popular o MDC do Log4j2 com os atributos do usuário
autenticado (a partir do
SecurityUtils
)- Ativado por padrão no esquema de segurança ‘jwt’
- Atributo Log4j2 MDC
errorTracking
renomeado paraerror.tracking
Versão 1.12.0
- Melhorado WebClientComponent:
- Cache da resolução de URL para melhor performance
- Agora suporte bypass de resolução se o endpoint for URL completa (http:// ou https://)
- Agora suporta endpoints com número arbitrário de níveis (ex: “/service/group/subgroup/operation”)
- Corrigido RemoteRouteResolver quando a propriedade se referia a uma operação específica
Versão 1.11.0
- Jobs:
- Agora evita execução concorrente do mesmo Job com os mesmos parâmetros, com intuito de mitigar risco de inconsistência de dados
- Adicionado
concurrency()
emBaseJob
- Sobrescreva este método para configurar o nível de concorrência específico para o Job
- É recomendado fazer isso para evitar paralelismo indesejado, caso ele possa causar inconsistência de dados
- O parâmentro
concurrency
na API (JobManager
e endpoints Actuator) agora é opcional- O valor padrão é 1 para rotinas iterativas e 2 para rotinas do tipo Produtor-Consumidor, que significa que o processo será sequencial por padrão (e não paralelo)
- O parâmentro
concurrency
não pode ser informado via API caso o métodoconcurrency()
esteja implementado no Job
- O valor padrão de
queueThreshold()
em rotinas do tipo Produtor-Consumidor agora é-1
, que significa que o motor de rotinas irá aguardar o esvaziamento da fila bem como o términdo de todos os consumos antes de realizar nova produção- O valor padrão anterior implicava produção e consumo concorrentes, o que poderia causar inconsistência de dados caso o Job não faça os devidos tratamentos
-
Adicionada API
jobManager.listJobSchedules()
e endpoint/actuator/cloudsupportjobs/schedules
que retorna a lista de definições de agendamentos de cada Job:{ "jobName": "(value)", "enabled": true, "definitions": [ { "cron;": "(value)", "zone;": "(value)", "fixedDelay": 999, "fixedDelayString;": "(value)", "fixedRate;": 999, "fixedRateString;": "(value)", "initialDelay;": 999, "initialDelayString;": "(value)", "timeUnit;": "(value)" } ] }
- Atualização de bibliotecas:
- Spring Boot de
3.3.0
para3.3.1
- Spring Boot de
Versão 1.10.5
- Corrigida consulta de histórico de Jobs em SQL Server, Oracle e PostgreSQL
- Dialeto é detectado automaticamente via metadados JDBC
- Compatibilidade: MySQL, H2, MariaDB, SQL Server 2012, Oracle 12 e PostgreSQL 8.4
Versão 1.10.4
- Adicionada biblioteca jaxb-api necessária para jjwt
Versão 1.10.3
- Pequenos ajustes na documentação
Versão 1.10.2
- Correção do erro “Job Engine error while trying to persist Job instance”, devido ao uso de Blob no lugar de Clob
Versão 1.10.1
- Pequenos ajustes na documentação
Versão 1.10.0
- Jobs:
- Adicionado método
start(jobParams)
emBaseProducerConsumerJob
, executado pelo motor antes da primeira produção - Corrigido erro no campo errorDetails, introduzido na versão anterior
- Adicionado método
- Segurança:
- Adicionado
SecurityUtils.isAuthenticated()
equivalente a @IsAuthenticated - Propriedade
cloudsupport.security.jwt.matches
renomeada paracloudsupport.security.jwt.paths
- Propriedade
cloudsupport.security.jwt.unsigned
renomeada paracloudsupport.security.jwt.always-trust
(padrão éfalse
)- Essa propriedade ativa um JwtDecoder que remove o bloco de assinatura de JWT (se existir)
- Adicionado
- Tratamento de exceções:
-
Propriedades abaixo foram substituídas pela única propriedade
cloudsupport.error.conventions.enabled
(padrão étrue
):cloudsupport.error.include-message-on-http-4xx cloudsupport.error.include-message-on-business-exception cloudsupport.error.hide-message-on-http-5xx cloudsupport.error.shorten-validation-errors cloudsupport.error.enable-web-tracking cloudsupport.jobs.save-stack-trace:false
- A nova propriedade ativa os seguintes recursos (web):
- BusinessExceptions: Será emitido o campo
message
no Error Whitelabel do Spring Boot, com código HTTP 422. A mensagem é projetada para ser mostrada para o usuário. - Jakarta/Hibernate Validations (
@Valid
): Será emitido o campofieldMessages
no Whitelabel contendo uma lista de{field, message}
, com código HTTP 422. O frontend poderá, opcionalmente, posicionar o erro no formulário com base no campo técnicofield
. As mensagens são projetadas para serem mostradas para o usuário. - Outros erros de cliente código 400: Será emitido o campo
message
no Error Whitelabel contendo o nome simples da classe de erro mais a mensagem. Também será emitido o campotracking
com o código de rastreamento. O erro será logado como WARN, incluindo o rastreamento, mas sem stack trace. Preferencialmente o frontend deve mostrar o rastreamento e não a mensagem. - Outros erros de cliente código não 400: Será emitido o campo
message
no Error Whitelabel contendo o nome simples da classe de erro mais a mensagem. Não há código de rastreamento nem log. O frontend pode mostrar uma mensagem genérica conforme o código HTTP. - Erros de servidor: Será suprimido o campo
message
por motivo de segurança. Será emitido o campotracking
com o código de rastreamento. O erro será logado como ERROR, incluindo o rastreamento, e com stack trace. O frontend deve mostrar o rastreamento. - Um filtro de servlet é ativado para evitar que erros sejam lançados no nível do container, pois gera duplicidade de log.
- Demais campos do Whitelabel serão emitidos conforme as configurações do Spring Boot.
-
Resumo:
Se Código HTTP Retorno Log Interface de Usuário BusinessException 422 message não mostrar a mensagem Exceção @Valid 422 fieldMessages não mostrar as mensagens de fieldMessages Outros erros de cliente 400 (mesmo) message, tracking WARN, sem stack trace preferencialmente mostrar o rastreamento e não a mensagem Outros erros de cliente não 400 (mesmo) message não mostrar uma mensagem genérica de acordo com o código Erros de servidor 500 tracking ERROR, com stack trace mostrar o rastreamento
- BusinessExceptions: Será emitido o campo
- A nova propriedade ativa os seguintes recursos (jobs):
- Campo
exitMessage
do JobExecution será populado com a mensagem no caso de BusinessException. Senão, receberá um resumo do erro incluindo o código de rastreamento, e o erro será logado como ERROR. - Campo
errorDetails
será nulo, vez que o erro constará no log.
- Campo
- Comportamento padrão se as convenções forem desativadas (web):
- Nenhuma personalização do Whitelabel
- Nenhuma tradução de validações Jakarta/Hibernate Validations
- Nenhum tratamento global de erros
- Comportamento padrão se as convenções forem desativadas (jobs):
- Campo
exitMessage
receberá a mensagem da exceção, não importa qual tipo dela - Campo
errorDetails
receberá o stack trace da exceção, não importa qual tipo dela - Todos os erros serão logados de maneira simples, sem código de rastreamento
- Campo
- Propriedade
include-binding-errors
removida do perfil cloudsupport-defaults (agora é o padrão do Spring Boot)
-
Versão 1.9.0
- Atualização de bibliotecas:
- Spring Boot de
2.6.3
para3.3.0
- Requer Java 17 ou posterior
javax.persistence
mudou parajakarta.persistence
javax.annotation
mudou parajakarta.annotation
javax.servlet
mudou parajakarta.servlet
javax.inject
mudou parajakarta.inject
javax.xml
mudou parajakarta.xml
- Pacotes mantidos em javax: javax.sql.* javax.transaction.xa.* javax.xml.* javax.naming.*
- Swagger de
1.6.5
para2.5.0
- SBA de
2.6.2
para3.2.3
- Spring Boot de
- Mudanças gerais:
- Removida anotação
@EnableDefaultConfig
- Removida classe
EnumItem
- Adicionada classe
CollectorUtils
com métodotoSingleton()
- Classe
Uid
movida paracloudsuport.services
- Pacote
cloudsupport.util
renomeado paracloudsupport.utils
- Classe
ResourceUtil
renomeada paraResourceUtils
- Classe
ExceptionHelper
renomeada paraExceptionUtils
- Adicionado método
messageFrom(throwable, tracking)
emExceptionUtils
- Adicionado método
getStackTrace(throwable)
emExceptionUtils
- Removido método
getRootSummary(throwable, lines)
deExceptionUtils
- Método
UidGenerator.get().next()
movido paraUidGenerator.nextLong()
- Adicionada propriedade
cloudsupport.json.default-config=false
que desativa a autoconfiguração do Jackson - Filtro
RequestLoggingFilter
agora despreza requisições Actuator, H2, Swagger UI e OpenAPI
- Removida anotação
- Jobs:
- O motor de rotinas e suas APIs (
JobManager
e endpoints Actuator) agora são autoconfigurados se existirem classes com@Job
- Removido JobExecution UID das respostas JSON dos endpoints Actuator
- Coluna
key
renomeada paraparamKey
na tabelajobParams
- Coluna
value
renomeada paraparamValue
na tabelajobParams
- Exceções não Business agora são rastreadas e o código é adicionado ao MDC do Log4j2
errorTracking
- Se
cloudsupport.jobs.save-stack-trace=true
(padrão é false), os stack traces de exceções não Business agora são salvos no camo errorDetails field da entidade jobExecution
- O motor de rotinas e suas APIs (
- Swagger:
- Bean
OpenAPI
agora é autoconfigurado e pode ser declarado pela aplicação - Novo type name resolver com prevenção de colisão (collision avoidance):
- TypeNameResolver que adiciona um contador de repetição no sufixo do nome dos models
- Propriedade
springdoc.use-fqn
pode ser mantidafalse
sem risco
- Bean
- Persistência:
- Bean
AuditorAware
agora é autoconfigurado e pode ser declarado pela aplicação:- Implementação padrão define o auditor como sendo
SecurityContextHolder.context.authentication.name
ou o claim JWT se a propriedadecloudsupport.auditing.auditor-jwt-claim
for definida
- Implementação padrão define o auditor como sendo
- Adicionado método
findByAttr
com opçãoLockModeType
em todos os estereótipos de classes de negócio - Adicionado método
findById
com opçãoLockModeType
em todos os estereótipos de classes de negócio - Adicionado método
findByUid
com opçãoLockModeType
em todos os estereótipos de classes de negócio - Os métodos de acesso à persistência em todos os estereótipos de classes de negócio agora são
protected
em vez depublic
- Bean
- Tratamento e log de exceções:
- Class
BusinessException
agora implementaErrorResponse
, em conformidade com o padrão de tratamento de exceções do Spring Web e aderente à RFC 9457 BusinessException
agora é mapeado para o status HTTP 422 (Unprocessable Entity)- Adicionada interface
TrackingGenerator
que permite a personalização da geração de códigos de rastreamento - Um gerador de códigos de rastreamento é autoconfigurado com base na propriedade
cloudsupport.error.tracking-generator
:"date"
(padrão): o código terá a sintaxe"<YYMMDD>-<serviceId>-<random>"
, ondeé os primeiros 4 dígitos do _hash_ de `spring.application.name` e é o hexa do UID de 54-bit do Cloudsupport. Substituições são feitas para melhor legibilidade e fonética (b -> h, c -> k, d -> x, e -> w). Exemplo: `"240530-5a5w-247612h6xk280"`. "uuid"
: o código será a versão Base64 do UUID Java (ex:"acRFQHdRSiuNW_g9vBoh3Q"
)- Ambos os geradores salvam o código no contexto MDC do Log4j2
errorTracking
- Um bean
HandlerExceptionResolver
é autoconfigurado secloudsupport.error.enable-web-tracking=true
(padrão) que captura exceções web não tratadas, gera o código de rastreamento, faz o log do erro e redireciona (por dispatch) para o caminho de erro do Spring Boot (server.error.path
ouerror.path
ou/error
)- O código de rastreamento é adicionado ao atributo
cloudsupport.error.tracking
do request
- O código de rastreamento é adicionado ao atributo
- Um bean
ErrorAttributes
é autoconfigurado para personalizar a página Error Whitelabel do Spring Boot:- Campo
message
será exibido em erros de cliente (4xx) secloudsupport.error.include-message-on-http-4xx=true
(padrão), tendo prioridade sobreserver.error.include-message
do Spring Boot. Esse recurso é útil quando se deseja não expor mensagens de erro para outros tipos de erros. - Campo
message
será exibido em exceçõesBusinessException
secloudsupport.error.include-message-on-business-exception=true
(padrão), tendo prioridade sobreserver.error.include-message
do Spring Boot e sobrecloudsupport.error.include-message-on-http-4xx
. - Campo
message
será ocultado em erros de servidor (5xx) secloudsupport.error.hide-message-on-http-5xx=true
(padrão), tendo prioridade sobreserver.error.include-message
do Spring Boot. - Campo (
errors
) é exibido de maneira mais concisa secloudsupport.error.shorten-validation-errors=true
(padrão). Afeta toda exceção que herda de BindingResult ou MethodValidationResult (ex: erros de bind ou erros de@Valid
). Cada erro na lista é mapeado para{field, message}
(para erros associados a campos) ou apenas{message}
. O campomessage
também é encurtado para"Validation failed"
. - Campo
tracking
será ocultado em erros de servidor (5xx).
- Campo
- Class
- Segurança:
- Adicionada anotação
@IsAuthenticated
como atalho para@PreAuthorize("isAuthenticated()")
- Adicionada anotação
@HasAuthority("name")
como atalho para@PreAuthorize("hasAuthority('{value}')")
- Adicionada anotação
@HasAnyAuthority({"'name1'", "'name2'"})
como atalho para@PreAuthorize("hasAnyAuthority('{value}')")
- Adicionada anotação
@LoggedIn
como atalho para Spring + Swagger@AuthenticationPrincipal @Parameter(hidden = true)
- Adicionada anotação
@LoggedInSubject
como atalho para o claim JWT"sub"
(padrão) - Adicionada anotação
@LoggedInIssuer
como atalho para o claim JWT"iss"
(padrão) - Adicionada anotação
@LoggedInAccountId
como atalho para o claim JWT"account_id"
(ex: tenant id, número da conta) - Adicionada anotação
@LoggedInPersonalId
como atalho para o claim JWT"personal_id"
(ex: CPF, SSN, etc) - Adicionada anotação
@LoggedInUserId
como atalho para o claim JWT"user_id"
(ex: matrícula, número de cadastro) - Adicionada anotação
@LoggedInDepartmentId
como atalho para o claim JWT"department_id"
(ex: código da unidade organizacional) - Adicionada anotação
@LoggedInUsername
como atalho para o claim JWT"username"
(ex: login) - Adicionada anotação
@LoggedInEmail
como atalho para o claim JWT"email"
- Adicionada anotação
@LoggedInPhoneNumber
como atalho para o claim JWT"phone_number"
- Adicionada anotação
@LoggedInName
como atalho para o claim JWT"name"
- Adicionada anotação
@LoggedInGivenName
como atalho para o claim JWT"given_name"
- Adicionada anotação
@LoggedInFamilyName
como atalho para o claim JWT"family_name"
- Adicionada anotação
@LoggedInNickname
como atalho para o claim JWT"nickname"
- Adicionada anotação
@LoggedInPicture
como atalho para o claim JWT"picture"
(ex: url) - Anotações
@LoggedIn*
retornamnull
se oprincipal
do token de autenticação não for um objetoJwt
- Adicionada propriedade
cloudsupport.security.allow-paths=auto
que autoconfigura endereços de acesso público, com as seguintes características:- Um filtro SecurityFilterChain que:
- Permite acesso anônimo para H2 Console (dinâmico, ex:
/h2-console
) - Permite acesso anônimo para Swagger UI (dinâmico, ex:
/swagger-ui
) - Permite acesso anônimo para OpenAPI (fixado em
/v3/api-docs
) - Permite acesso anônimo para Actuator (dinâmico, ex:
/actuator
) - Desativa CSRF
- Ativa CORS (veja abaixo o filtro autoconfigurado de CORS)
- Permite iframe na mesma origem (requisito do H2 Console)
- Tem Order(1)
- Permite acesso anônimo para H2 Console (dinâmico, ex:
- Se a propriedade for diferente de
auto
, então o filtro será aplicado para a lista de endereços separados por vírgula
- Um filtro SecurityFilterChain que:
- Adicionada propriedade
cloudsupport.security.scheme=jwt
que autoconfigura uma pilha de segurança então chamada de ‘jwt’, com as seguintes características:- Um filtro SecurityFilterChain que:
- Ativa autorização por Oauth2 ResourceServer via JWT
- Desativa form login (statefull)
- Desativa BASIC login
- Desativa CSRF
- Ativa CORS (veja abaixo o filtro autoconfigurado de CORS)
- Se aplica a todas as rotas (padrão) ou àquelas definidas em
cloudsupport.security.jwt.matches
(lista separada por vírgula) - Não aplica requisito de autenticação obrigatória
- Adiciona o filtro Cloudsupport
WebDetailsFilter
, o qual defineWebDetails
como sendo o objeto de details do token de autenticação - Tem Order(2)
- Suporte a hidratação de campos no
WebDetails
(um Map) por beans do tipoWebDetailsAttributesSource
, que permite à aplicação prover dados extras - Ativado um
WebDetailsAttributesSource
padrão que injetaorigin_ip
,origin_proto
,remote_addr
esession_id
noWebDetails
- Ativada segurança de método (
@PreAuthorize
e@PostAuthorize
) - Ativado templating de meta-annotation em segurança de método
- Ativado um JwtAuthenticationConverter que carrega as permissões (authorities) a partir do claim JWT
definido na propriedade
cloudsupport.security.jwt.authorities-claim
(por padrão"roles"
) - Ativado o security scheme no Swagger de nome
"JWT"
(bearer) - Ativado um personalizador Swagger que automaticamente configura a documentação de requisito de segurança
equivalente a
@SecurityRequirement(name = "JWT")
nos endpoints anotados com@HasAuthority
,@HasAnyAuthority
ou@IsAuthenticated
, em que as permissões (authorities) são inclusas como scopes do SecurityRequirement do Swagger - Ativado um personalizador Swagger que automaticamente adiciona os nomes da permissões na documentação dos
resumos dos endpoints (summary) anotados com
@HasAuthority
,@HasAnyAuthority
ou@IsAuthenticated
, uma vez que o Swagger UI não suporta nativamente a exibição das permissões (scopes) -
Exemplo de como o código fica simplificado:
// Spring puro: @PreAuthorize("hasAuthority('permission')") @SecurityRequirement(name = "JWT") @Tag(name = "group") public void operation( @AuthenticationPrincipal(expression = "#this instanceof T(org.springframework.security.oauth2.jwt.Jwt) ? claims['name'] : null") @Parameter(hidden = true) String name) { } // Com Cloudsupport: @HasAuthority("permission") public void operation( @LoggedInName String name) { }
- Um filtro SecurityFilterChain que:
- Adicionada anotação Swagger
@RequiresJwt
como atalho para@SecurityRequirement(name = "JWT")
- Adicionado suporte a JWT não assinado, recurso ativado por
cloudsupport.security.jwt.unsigned=true
- Útil para testes locais da aplicação ou em ambientes confiáveis (ex: microsserviços protegidos por API Gateway)
- Adicionado Filtro CORS autoconfigurado que permite todas as origens, todos os headers e todos os métodos registrado para todos os paths, uma vez que o microsserviço é por padrão projetado para utilização em front mobile e com requisições autenticadas
- Class
SecurityContext
renomeada paraSecurityUtils
- Removido
SecurityUtils.getUsername()
- Adicionado
SecurityUtils.getLogin()
como atalho paraSecurityContextHolder.context.authentication.name
(se uso de JWT, este método retornará o claim ‘sub’) - Adicionado
SecurityUtils.getOriginIp()
como atalho paraSecurityContextHolder.context.authentication.details.attributes['origin_ip']
- Adicionado
SecurityUtils.getOriginProto()
como atalho paraSecurityContextHolder.context.authentication.details.attributes['origin_proto']
- Adicionado
SecurityUtils.getWebDetail('key')
como atalho paraSecurityContextHolder.context.authentication.details.attributes['key']
- Adicionado
SecurityUtils.getWebDetails()
como atalho paraSecurityContextHolder.context.authentication.details
- Adicionado
SecurityUtils.getLoggedIn()
equivalente a @LoggedIn - Adicionado
SecurityUtils.getLoggedInSubject()
equivalente a @LoggedInSubject - Adicionado
SecurityUtils.getLoggedInIssuer()
equivalente a @LoggedInIssuer - Adicionado
SecurityUtils.getLoggedInAccountId()
equivalente a @LoggedInAccountId - Adicionado
SecurityUtils.getLoggedInPersonalId()
equivalente a @LoggedInPersonalId - Adicionado
SecurityUtils.getLoggedInUserId()
equivalente a @LoggedInUserId - Adicionado
SecurityUtils.getLoggedInDepartmentId()
equivalente a @LoggedInDepartmentId - Adicionado
SecurityUtils.getLoggedInUsername()
equivalente a @LoggedInUsername - Adicionado
SecurityUtils.getLoggedInPhoneNumber()
equivalente a @LoggedInPhoneNumber - Adicionado
SecurityUtils.getLoggedInEmail()
equivalente a @LoggedInEmail - Adicionado
SecurityUtils.getLoggedInName()
equivalente a @LoggedInName - Adicionado
SecurityUtils.getLoggedInGivenName()
equivalente a @LoggedInGivenName - Adicionado
SecurityUtils.getLoggedInFamilyName()
equivalente a @LoggedInFamilyName - Adicionado
SecurityUtils.getLoggedInNickname()
equivalente a @LoggedInNickname - Adicionado
SecurityUtils.getLoggedInPicture()
equivalente a @LoggedInPicture - Adicionado
SecurityUtils.hasAuthority()
equivalente a @hasAuthority - Adicionado
SecurityUtils.hasAnyAuthority()
equivalente a @hasAnyAuthority - Adicionadas bibliotecas
oauth2-resource-server
ejjwt
para suporte a JWT
- Adicionada anotação
- Integração (remotes):
- O Token bearer agora é propagado caso seja utilizada a API
WebClientComponent.authenticated()
,authenticatedGet()
ouauthenticatedPost()
, assim como os cabeçalhos X-Forwarded-For e X-Forwarded-Proto - Métodos
WebClientComponent.get()
,post()
,authenticatedGet()
eauthenticatedPost()
resolvem a URL do endpoint viaRouteResolver
do Cloudsupport - Se um bean do tipo
WebClient.Builder
for declarado na aplicação, oWebClientComponent
do Cloudsupport construirá seus clients por cima do builder provido, o que permite à aplicação adicionar regras como filtros de load balancing (ex: se@LoadBalanced
for utilizado)
- O Token bearer agora é propagado caso seja utilizada a API
- Profile:
-
O profile padrão sugerido
cloudsupport-defaults.properties
foi simplificado e ajustado:# ---------------------- # Documentation # ---------------------- # Springdoc tag per controller is not friendly to the Feature Service pattern springdoc.auto-tag-classes=false # Default is '/swagger-ui.html', but Swagger redirects to '/swagger-ui' springdoc.swagger-ui.path=/swagger-ui # Collapsed models springdoc.swagger-ui.defaultModelsExpandDepth=-1 springdoc.swagger-ui.defaultModelExpandDepth=2 # ---------------------- # Actuator # ---------------------- management.endpoints.web.exposure.include=* # ---------------------- # Error Whitelabel # ---------------------- # Useful to the frontend, as the field name and expected type are presented in 'errors' of the Whitelabel server.error.include-binding-errors=ALWAYS # ---------------------- # Logging # Note: Will take effect if using Spring Boot Log Extensions (eg: log4j2-spring.xml, not log4j2.xml) # ---------------------- # Avoids many 'WARN DefaultHandlerExceptionResolver : Resolved' # Spring Boot 'spring.mvc.log-resolved-exception' does not work for all resolvers # (issue https://github.com/spring-projects/spring-boot/issues/29706) logging.level.org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver=error # Default Cloudsupport log level logging.level.cloudsupport.spring.AppLifecycle=info # ---------------------- # Persistence JPA # ---------------------- # This interceptor safeguards the source code by preventing JPA flush operations outside the # transaction scope or within readonly transactions. In both scenarios, the underlying database # operates in "auto commit mode," making erroneous flushing potentially detrimental to data integrity. spring.jpa.properties.hibernate.session_factory.interceptor=cloudsupport.persistence.HibernateInterceptor # Simple naming strategy spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl # Spring MVC defaults to creating a new JPA session per request, which can result in # unstable behavior of services due to potential differences in JPA sessions between service flows. # It is preferred to synchronize session creation with the @Transactional scope. spring.jpa.open-in-view=false # If opting in to show SQL, format the SQL output spring.jpa.properties.hibernate.format_sql=true
-
Versão 1.8.0
- Jobs (Motor):
- Agora suporta ativação/desativação dos agendamentos de Job via JobConfigurations
- JobConfigurations é persistido no banco de dados se o JobRepository JDBC for ativado
- Adicionado método
jobManager.listConfigurations()
(lista as configurações) - Adicionado método
jobManager.reloadConfigurations()
(recarrega as configurações a partir do banco de dados) - Adicionado método
jobManager.getConfiguration(jobName, key)
- Adicionado método
jobManager.setConfiguration(jobName, key, value)
- Adicionado método
jobManager.listHistory(...)
(lista o histórico de execuções) - Alterado método
jobManager.listJobNames()
paralistRegistryEntries()
- Campos de data agora são salvos em UTC
- Melhorada a performance do Producer-Consumer
- Obs: lembre de configurar
spring.task.scheduling.pool.size
(limite para o total de agendamentos em execução do Spring) - As entidades retornadas por
jobManager
agora são apenas POJO - As entidades agora utilizam
java.util.Date
e status comoString
devido a retrocompatibilidade e aderência ao Actuator:- JobExecution
- JobInstance
- JobParams
- JobConfigurations
- JobHistory
- JobRegistry
- JobParams agora são padronizados (ordenados e com duplicidades removidas)
- Jobs (repostiório):
- Adicionado In-Memory JobRepository, que permite utilização do módulo de Jobs sem necessidade em banco de dados (full JVM)
- Adicionada propriedade Spring para seleção do JobRepository:
cloudsupport.jobs.repository=memory|jdbc
(padrão émemory
) - Propriedade adicional se o modo for
jdbc
:cloudsupport.jobs.repository.jdbc.tablePrefix
(padrão é""
)
- Jobs (gerenciamento via Actuator):
- Adicionado endpoint
/actuator/cloudsupportjobs/wakeup?[jobName][instanceUid]
(notifica o Job para acordar suas threads internas) - Adicionado endpoint
/actuator/cloudsupportjobs/configurations?[reload=true]
(lista as configurações de Jobs) - Adicionado endpoint
/actuator/cloudsupportjobs/configuration?jobName&key[&value]
(lê ou atualiza uma configuração, ex:"scheduling=true|false"
) - Adicionado endpoint
/actuator/cloudsupportjobs/history?[jobName][&executionStatus][&exitStatus][&instanceUid][&dateFrom][&dateTo][&offset][&maxResults]
(lista o histórico de execuções)
- Adicionado endpoint
- Para ativar o agendamento de Jobs, ambos os itens abaixo devem ser
true
:- Propriedade do Spring Boot
cloudsupport.jobs.scheduling.enabled=true|false
. Padrão éfalse
. - Configuração do Job
scheduling=true|false
. Padrão étrue
. - Notas técnicas:
- A propriedade do Spring Boot faz as anotações de classe
@Schedule
surtirem efeito. - A configuração do Job faz o método
BaseSchedule.runJob
surtir efeito. - A configuração do Job é resolvida dinamicamente a cada gatilho do
@Scheduled
.
- A propriedade do Spring Boot faz as anotações de classe
- Propriedade do Spring Boot
Versão 1.7.0
- Jobs (Motor):
- Removida classe
BaseBatchProducerConsumerJob
em favor da novaBaseProducerConsumerJob
- Removida classe
BaseContinuousProducerConsumerJob
em favor da novaBaseProducerConsumerJob
- Adicionada classe
BaseProducerConsumerJob
que oferece uma API mais rica para o padrão Produtor-Consumidor:- Método
shouldProduceMore()
ativa a produção periódica - Método
queueThreshold()
configura dinamicamente o limiar do buffer que dispara nova produção - Método
productionRetryDelay()
facilmente configura uma solução robusta de atraso não blocante entre produções - Método
wakeUp()
para acordar as threads do Job, o que permite a construção de um mecanismo de produção contínua (stream processing)
- Método
- Removido método
BaseJob.elapsed()
, pois poderia conduzir o dev para uma implementação ruim de backoff delay - Removido método
BaseJob.sleep()
, pois poderia conduzir o dev para uma implementação ruim de backoff delay - Alterado método
jobManager.getRunningJobs()
paralistRunningJobs()
- Adicionado método
jobManager.listJobNames()
- Adicionado método
jobManager.requestStop(jobExecution|instanceUid)
- Adicionado método
jobManager.awaitTermination(jobExecution|instanceUid)
- Adicionado método
jobManager.wakeUp(jobExecution|instanceUid)
(notifica o Job para acordar suas threads internas) - Adicionado método
jobManager.wakeUpAll(jobName)
- Removidos todos os métodos de operação da entidade
jobExecution
- Aprimoramentos menores no motor de execução
- Removida classe
- Jobs (gerenciamento via Actuator):
- Adicionado endpoint
/actuator/cloudsupportjobs/registry
(lista os possíveis Jobs) - Adicionado endpoint
/actuator/cloudsupportjobs/running
(lista os Jobs em andamento) - Adicionado endpoint
/actuator/cloudsupportjobs/stop?instanceUid
(solicita interrupção do Job) - Adicionado endpoint
/actuator/cloudsupportjobs/start?jobName[&jobParams]&concurrency
(inicia um Job)
- Adicionado endpoint
- Adicionado Cloudsupport Info Actuator Contributor para enriquecer
/actuator/info
com dados gerais da aplicação:- Versões dos principais frameworks
- Estado do agendamento de Jobs
- Totais de funcionalidades (Jobs e webservices)
- Actuator endpoint
healthReadiness
alterado parahealthreadiness
Versão 1.6.0
- Adicionada propriedade
cloudsupport.jobs.scheduling.enabled=true
que ativa classes@Schedule
- Adicionado método
jobManager.start(clazz, jobParams, concurrency)
BaseSchedule.runJob
agora localiza o Job por convenção de nomes (parâmetrojobName
suprimido), nova API:- Método
BaseSchedule.runJob()
para executar um Job de maneira assíncrona, com 1 thread e nenhum parâmetro - Método
BaseSchedule.runJob(concurrency)
para executar sem parâmetros - Método
BaseSchedule.runJob(jobParams)
para executar com 1 thread de trabalho - Método
BaseSchedule.runJob(jobParams, concurrency)
- Método
Versão 1.5.0
- Adicionados
@Schedule
eBaseSchedule
para agendamento de Jobs via Spring Scheduled Tasks
Versão 1.4.0
- Propriedades
cloudsupport.remote.*
alteradas paracloudsupport.remotes.*
- Propriedades
cloudsupport.job.*
alteradas paracloudsupport.jobs.*
- Classes Cloudsupport movidas:
- Do pacote
cloudsupport.business
paracloudsupport.services
- Do pacote
cloudsupport.business.job
paracloudsupport.services.jobs
- Do pacote
cloudsupport.business.ws
paracloudsupport.services.web
- Do pacote
cloudsupport.remote
paracloudsupport.remotes
- Do pacote
- Convenção de nomes de pacote para classes @Ws alterada:
- De
[...].<serviceName>.business.features.ws.<group>.<featureName>.v<num>
- Para
[...].<serviceName>.services.web.<group>.<featureName>.v<num>
- De
Versão 1.3.0
- Propriedades
app.remote.route.*
alteradas paracloudsupport.remote.route.*
- Propriedades
app.job.repositoryJdbc.*
alteradas paracloudsupport.job.repositoryJdbc.*
Versão 1.2.0
- Melhorado
PageableQuery.fetch()
para suportar múltiplas invocações
Versão 1.1.0
- CORS permitido para todos os caminhos
Versão 1.0.1
- Correção em
BaseGenericEntity
para reconhecer campos de ID, não apenas métodos de ID
Versão 1.0.0
- Primeira versão
- SpringBoot: 2.6.3
- springdoc-openapi: 1.6.5
- SBA: 2.6.2