Um microserviço REST robusto desenvolvido com Spring Boot 3.5.9 e Java 21 para gerenciar licenças de software, ativações, validações e controle de produtos com suporte a hardware vinculado e funcionalidades granulares.
- Gerenciamento de Produtos: Criar, atualizar, consultar e deletar produtos
- Gerenciamento de Licenças: Operações CRUD com suporte a chaves únicas
- Ativação de Licenças: Sistema de ativação com vinculação a hardware
- Validação de Licenças: Verificação de status, expiração e hardware vinculado
- Funcionalidades Granulares: Controle de features habilitadas por licença
- Limite de Usuários: Suporte a restrição de máximo de usuários por licença
- Tratamento de Exceções: Handler global para erros e validações
- Documentação Automática: Swagger UI/OpenAPI 3.0 integrado
- Persistência: Spring Data JPA com PostgreSQL
- Segurança: Spring Security configurado
| Tecnologia | Versão | Propósito |
|---|---|---|
| Java | 21 | Linguagem base |
| Spring Boot | 3.5.9 | Framework principal |
| Spring Data JPA | - | ORM/Persistência |
| Spring Security | - | Autenticação e autorização |
| Spring Validation | - | Validação de dados |
| PostgreSQL | - | Banco de dados |
| Lombok | - | Redução de boilerplate |
| Springdoc OpenAPI | 2.3.0 | Documentação API |
- Java 21 instalado
- PostgreSQL instalado e rodando
- Maven 3.8.1+
-
Clone o repositório
git clone https://github.com/seu-usuario/licensing.git cd licensing -
Configure o banco de dados
Crie um banco de dados PostgreSQL:
CREATE DATABASE licensing_db;
-
Configure as variáveis de ambiente
Crie um arquivo
application-local.properties:spring.datasource.url=jdbc:postgresql://localhost:5432/licensing_db spring.datasource.username=seu_usuario spring.datasource.password=sua_senha spring.jpa.hibernate.ddl-auto=update
-
Construa e execute
mvn clean install mvn spring-boot:run
-
Acesse a documentação
http://localhost:8080/swagger-ui.html
src/main/java/br/com/sistema/licensing/
├── controller/
│ ├── LicenseController.java # Endpoints de licenças
│ └── ProductController.java # Endpoints de produtos
├── model/
│ ├── License.java # Entidade de Licença
│ ├── Product.java # Entidade de Produto
│ └── LicenseStatus.java # Enum de status
├── services/
│ ├── LicenseService.java # Lógica de licenças
│ └── ProductService.java # Lógica de produtos
├── repositories/
│ ├── LicenseRepository.java # Acesso a licenças
│ └── ProductRepository.java # Acesso a produtos
├── dtos/
│ ├── LicenseRequest.java # DTO de entrada
│ ├── LicenseResponse.java # DTO de saída
│ ├── LicenseValidationRequest.java
│ ├── ProductRequest.java
│ └── ProductResponse.java
├── exceptions/
│ ├── GlobalExceptionHandler.java # Handler global
│ ├── LicenseException.java
│ └── ResourceNotFoundException.java
└── configurations/
└── OpenApiConfig.java # Configuração Swagger
POST /api/products- Criar produtoGET /api/products- Listar todosGET /api/products/{id}- Obter por IDPUT /api/products/{id}- AtualizarDELETE /api/products/{id}- Deletar
POST /api/licenses- Criar licençaGET /api/licenses- Listar todasGET /api/licenses/{licenseKey}- Obter por chavePUT /api/licenses/{licenseKey}- AtualizarDELETE /api/licenses/{licenseKey}- Deletar
POST /api/licenses/activate- Ativar licençaPOST /api/licenses/validate- Validar licença
{
"id": 1,
"name": "MeuSistema",
"description": "Sistema de gestão empresarial"
}{
"licenseKey": "ABC123XYZ789",
"productName": "MeuSistema",
"licensedTo": "Empresa LTDA",
"issueDate": "2024-01-01T00:00:00",
"expirationDate": "2025-12-31T23:59:59",
"status": "ACTIVE",
"enabledFeatures": ["RELATORIOS", "INTEGRACAO_API"],
"maxUsers": 10,
"hardwareId": "HW123456",
"activationDate": "2024-01-15T10:30:00"
}ACTIVE- Licença ativaPENDING_ACTIVATION- Aguardando ativaçãoEXPIRED- ExpiradaREVOKED- RevogadaSUSPENDED- Suspensa
O projeto implementa validações em múltiplas camadas:
- DTOs: Anotações Jakarta Validation (@NotBlank, @Future, @Size, etc.)
- Entidades: Constraints de banco de dados
- Serviços: Lógica de negócio customizada
- Controladores: Binding automático com @Valid
// Licença deve ter produto cadastrado
// Chave deve ter entre 10-50 caracteres
// Data de expiração deve ser no futuro
// Data de emissão não pode ser depois da expiraçãoA aplicação retorna respostas estruturadas para erros:
{
"timestamp": "2024-01-15T10:30:00",
"message": "License not found with key: INVALID_KEY",
"details": "uri=/api/licenses/INVALID_KEY",
"validationErrors": null
}Códigos HTTP retornados:
200 OK- Sucesso201 Created- Recurso criado204 No Content- Deletado com sucesso400 Bad Request- Erro de validação404 Not Found- Recurso não encontrado500 Internal Server Error- Erro interno
- Cliente solicita ativação com licenseKey, productName e hardwareId
- Serviço valida se licença existe e pertence ao produto
- Verifica se já está ativa (se sim, permite reativação em novo hardware)
- Valida status e data de expiração
- Define status como ACTIVE e registra data/hardware de ativação
- Cliente solicita validação com licenseKey e productName
- Serviço valida se licença existe
- Verifica status, expiração e hardware vinculado
- Retorna status detalhado da licença
curl -X POST http://localhost:8080/api/products \
-H "Content-Type: application/json" \
-d '{
"name": "MeuSistema",
"description": "Sistema de gestão"
}'curl -X POST http://localhost:8080/api/licenses \
-H "Content-Type: application/json" \
-d '{
"productName": "MeuSistema",
"licenseKey": "ABC123XYZ789",
"licensedTo": "Empresa LTDA",
"issueDate": "2024-01-01T00:00:00",
"expirationDate": "2025-12-31T23:59:59",
"status": "PENDING_ACTIVATION",
"enabledFeatures": ["RELATORIOS", "INTEGRACAO"],
"maxUsers": 10
}'curl -X POST http://localhost:8080/api/licenses/activate \
-H "Content-Type: application/json" \
-d '{
"licenseKey": "ABC123XYZ789",
"productName": "MeuSistema",
"hardwareId": "HW123456"
}'Execute os testes unitários e de integração:
mvn testAcesse a documentação interativa em:
- Swagger UI: http://localhost:8080/swagger-ui.html
- OpenAPI JSON: http://localhost:8080/api-docs
spring.profiles.active=local
spring.jpa.show-sql=truespring.profiles.active=prod
logging.level.root=INFOConfigure variáveis de ambiente para produção:
POSTGRES_HOSTPOSTGRES_PORTPOSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORD
- Faça um Fork do projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abra um Pull Request
Este projeto está licenciado sob a MIT License - veja o arquivo LICENSE para detalhes.
César Augusto
- Email: cesar.augusto.rj1@gmail.com
- Portfolio: https://portfolio.cesaravb.com.br/
Para suporte, abra uma issue no repositório ou entre em contato pelo email.
Última atualização: Janeiro 2026