Files
SD/main/docs/SERIALIZATION_SPECIFICATION.md
2025-10-23 20:08:26 +01:00

371 lines
10 KiB
Markdown

# Especificação do Formato de Serialização
## 1. Visão Geral
Este documento descreve as estratégias de serialização para a comunicação entre processos no sistema de simulação de tráfego distribuído. A serialização é necessária para transmitir objetos Java através de sockets entre diferentes processos (cruzamentos, coordenador, dashboard).
## 2. Requisitos
### 2.1 Objetos a Serializar
Os principais objetos que precisam ser serializados são:
- **Vehicle**: Contém estado completo do veículo (id, tipo, rota, métricas)
- **Message**: Container para todas as mensagens entre processos
- **Estatísticas**: Dados agregados dos cruzamentos e semáforos
### 2.2 Requisitos Funcionais
- **Integridade**: Todos os dados devem ser preservados durante a serialização/desserialização
- **Compatibilidade**: Suporte para evolução de classes (adicionar campos)
- **Performance**: Latência mínima para não impactar a simulação
- **Depuração**: Capacidade de inspecionar mensagens facilmente
### 2.3 Requisitos Não-Funcionais
- Tamanho da mensagem otimizado
- Fácil manutenção e extensibilidade
- Compatibilidade com ferramentas de monitorização
---
## 3. Comparação: Java Serialization vs JSON
### 3.1 Java Serialization
#### Vantagens ✅
1. **Nativo do Java**
- Sem dependências externas
- Suporte built-in na JVM
- Integração direta com Serializable
2. **Preservação de Tipos**
- Mantém tipos Java exatos
- Serializa grafo completo de objetos
- Suporte automático para herança
3. **Performance de Escrita**
- Serialização binária mais rápida
- Menos overhead de conversão
- ObjectOutputStream otimizado
4. **Facilidade de Implementação**
- Basta implementar Serializable
- Controle fino com serialVersionUID
- Métodos customizados: writeObject/readObject
#### Desvantagens ❌
1. **Acoplamento Java**
- Apenas entre aplicações Java
- Dificulta interoperabilidade futura
- Formato proprietário
2. **Tamanho das Mensagens**
- Formato binário verboso
- Inclui metadata de classes
- 2-3x maior que JSON compacto
3. **Depuração Difícil**
- Formato binário não legível
- Necessita ferramentas especiais
- Difícil inspecionar mensagens
4. **Problemas de Segurança**
- Vulnerabilidades conhecidas (CVEs)
- Desserialização insegura
- Necessita validação cuidadosa
5. **Evolução de Classes**
- serialVersionUID requer gestão manual
- Quebra compatibilidade facilmente
- Difícil manter versões diferentes
#### Métricas Estimadas
```
Tamanho Médio: 400-600 bytes (Vehicle completo)
Latência: 0.5-1ms (serialização + rede local)
Throughput: ~10,000 msgs/s
```
---
### 3.2 JSON (com Gson/Jackson)
#### Vantagens ✅
1. **Legibilidade Humana**
- Formato texto simples
- Fácil depuração
- Inspecionável com ferramentas comuns
2. **Interoperabilidade**
- Padrão universal
- Facilita integração futura
- Dashboard web, APIs, etc.
3. **Tamanho Otimizado**
- Formato compacto
- ~40% menor que Java Serialization
- Compressão opcional (gzip)
4. **Evolução Flexível**
- Campos opcionais nativos
- Backward/forward compatibility
- Versionamento natural
5. **Ferramentas e Ecossistema**
- Bibliotecas maduras (Gson, Jackson)
- Validação com JSON Schema
- Suporte a logs estruturados
6. **Segurança**
- Sem execução de código
- Validação mais simples
- Menos vetores de ataque
#### Desvantagens ❌
1. **Dependência Externa**
- Necessita biblioteca (Gson/Jackson)
- Aumenta tamanho do JAR
- Possível quebra de dependência
2. **Performance de Conversão**
- Parsing de texto
- Reflexão Java
- ~20-30% mais lento que binário
3. **Tipos Perdidos**
- Necessita type hints
- Problemas com genéricos
- Enums requerem atenção
4. **Memória**
- String temporárias
- Maior uso de heap
- GC mais frequente
#### Métricas Estimadas
```
Tamanho Médio: 250-350 bytes (Vehicle completo)
Latência: 0.8-1.5ms (conversão + rede local)
Throughput: ~8,000 msgs/s
```
---
## 4. Decisão e Recomendação
### 4.1 Análise de Contexto
**Características do Projeto:**
- Sistema distribuído Java-only (curto prazo)
- Comunicação intra-rede local (baixa latência)
- Volume moderado de mensagens (~100-1000/s)
- Necessidade de depuração durante desenvolvimento
- Potencial expansão futura (dashboard web)
### 4.2 Recomendação: **JSON (Gson)**
#### Justificativa
1. **Desenvolvimento e Depuração** 🔍
- A fase atual do projeto requer debugging extensivo
- JSON facilita inspeção de mensagens
- Logs legíveis sem ferramentas especiais
2. **Manutenibilidade** 🔧
- Mais fácil para equipe aprender/modificar
- Evolução de protocolo mais simples
- Menos problemas de compatibilidade
3. **Extensibilidade** 🚀
- Dashboard web futuramente
- APIs REST potenciais
- Integração com ferramentas de monitorização
4. **Performance Aceitável**
- Diferença de latência irrelevante (< 1ms)
- Volume de mensagens não é crítico
- Rede local minimiza overhead
5. **Segurança** 🔒
- Evita vulnerabilidades de Java Serialization
- Validação mais simples e segura
### 4.3 Quando Usar Java Serialization
Java Serialization seria preferível se:
- Performance crítica (> 100k msgs/s)
- Objetos muito complexos com referências circulares
- Garantia de ambiente Java puro permanente
- Necessidade de preservar estado exato (locks, transient)
---
## 5. Implementação Recomendada
### 5.1 Arquitetura de Serialização
```
┌─────────────────────────────────────────┐
│ Application Layer │
│ (Vehicle, Message, Statistics) │
└─────────────────┬───────────────────────┘
┌─────────────────▼───────────────────────┐
│ Serialization Interface │
│ - serialize(Object): byte[] │
│ - deserialize(byte[], Class<T>): T │
└─────────────────┬───────────────────────┘
┌─────────┴─────────┐
│ │
┌───────▼──────┐ ┌────────▼─────────┐
│ JsonSerializer│ │JavaSerializer │
│ (Gson-based) │ │(ObjectStream) │
└───────────────┘ └──────────────────┘
```
### 5.2 Estrutura de Mensagens JSON
#### Exemplo 1: Transferência de Veículo
```json
{
"messageId": "a3c5e7f9-1234-5678-90ab-cdef12345678",
"type": "VEHICLE_TRANSFER",
"senderId": "Cr1",
"destinationId": "Cr2",
"timestamp": 1729595234567,
"payload": {
"id": "V123",
"type": "LIGHT",
"entryTime": 15.7,
"route": ["Cr1", "Cr2", "Cr5", "S"],
"currentRouteIndex": 1,
"totalWaitingTime": 3.2,
"totalCrossingTime": 1.8
}
}
```
#### Exemplo 2: Atualização de Estatísticas
```json
{
"messageId": "b4d6e8f0-2345-6789-01bc-def123456789",
"type": "STATS_UPDATE",
"senderId": "Cr3",
"destinationId": "Dashboard",
"timestamp": 1729595234789,
"payload": {
"intersectionId": "Cr3",
"queueLengths": {
"North": 5,
"South": 3,
"East": 7,
"West": 2
},
"vehiclesProcessed": 142,
"averageWaitTime": 4.5
}
}
```
### 5.3 Biblioteca Escolhida: **Gson**
**Por que Gson (não Jackson)?**
- ✅ Mais simples e leve
- ✅ Menos configuração necessária
- ✅ API mais intuitiva para iniciantes
- ✅ Melhor para modelos simples (nosso caso)
- ⚠️ Jackson seria melhor para: streaming, performance extrema, binding complexo
---
## 6. Plano de Implementação
### Fase 1: Setup
- [x] Adicionar dependência Gson ao pom.xml
- [ ] Criar interface `MessageSerializer`
- [ ] Implementar `JsonMessageSerializer`
- [ ] Implementar `JavaMessageSerializer` (fallback)
### Fase 2: Adapters
- [ ] Criar adaptadores Gson para classes do modelo
- [ ] Configurar serialização customizada se necessário
- [ ] Implementar testes unitários
### Fase 3: Integração
- [ ] Integrar serializer nos sockets
- [ ] Adicionar logs de mensagens
- [ ] Implementar mecanismo de versionamento
### Fase 4: Otimização (Opcional)
- [ ] Implementar compressão (gzip)
- [ ] Pool de serializers
- [ ] Métricas de performance
---
## 7. Estrutura de Arquivos
```
src/main/java/sd/
├── serialization/
│ ├── MessageSerializer.java # Interface comum
│ ├── JsonMessageSerializer.java # Implementação Gson
│ ├── JavaMessageSerializer.java # Implementação nativa
│ ├── SerializerFactory.java # Factory pattern
│ └── adapters/ # Type adapters Gson
│ ├── VehicleAdapter.java
│ └── MessageAdapter.java
└── network/
├── MessageSocket.java # Wrapper para socket
└── MessageProtocol.java # Protocolo de comunicação
```
---
## 8. Considerações Finais
### 8.1 Boas Práticas
1. **Versionamento**: Incluir campo `version` nas mensagens
2. **Validação**: Validar mensagens após desserialização
3. **Logging**: Logar mensagens em desenvolvimento (desabilitar em produção)
4. **Exceções**: Tratar erros de serialização gracefully
5. **Testes**: Testar serialização round-trip para todas as classes
### 8.2 Monitorização
- Tamanho médio de mensagens
- Latência de serialização/desserialização
- Taxa de erros de serialização
- Throughput de mensagens
### 8.3 Documentação
Cada tipo de mensagem deve ser documentado com:
- Propósito
- Estrutura JSON
- Exemplo
- Sender/Receiver esperado
- Comportamento em caso de erro
---
## 9. Referências
- [Gson User Guide](https://github.com/google/gson/blob/master/UserGuide.md)
- [Java Serialization Specification](https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html)
- [JSON Schema](https://json-schema.org/)
- [Effective Java - Item 87: Consider using a custom serialized form](https://www.oreilly.com/library/view/effective-java/9780134686097/)
---
**Documento criado em**: 22 de outubro de 2025
**Versão**: 1.0
**Autor**: Equipa SD - Trabalho Prático