Skip to content

Commit

Permalink
modify structure of domain layer to fully adhere to domain driven design
Browse files Browse the repository at this point in the history
  • Loading branch information
MGTheTrain committed Nov 19, 2024
1 parent c33849b commit 86f4c62
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 185 deletions.
6 changes: 6 additions & 0 deletions docs/architecture-decision-record/ddd.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ Incorporating DDD as an architecture decision impacts the structure and developm
│ │ └── ...
│ ├── app
│ ├── domain
│ └── blob
│ └── key
│ └── permission
│ ├── infrastructure
│ └── persistence
└── test
├── data
├── integration
│ ├── domain
│ └── blob
│ └── key
│ └── permission
│ ├── infrastructure
│ └── persistence
└── unit
Expand Down
28 changes: 28 additions & 0 deletions internal/domain/blob/contract.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package blob

// BlobManagement defines methods for managing blob operations.
type BlobManagement interface {
// Upload handles the upload of blobs from file paths.
// Returns the created Blobs metadata and any error encountered.
Upload(filePath []string) ([]*Blob, error)

// Download retrieves a blob by its ID and name, returning the metadata and file data.
// Returns the Blob metadata, file data as a byte slice, and any error.
Download(blobId, blobName string) (*Blob, []byte, error)

// DeleteByID removes a blob by its ID.
// Returns any error encountered.
DeleteByID(blobId string) error
}

// BlobMetadataManagement defines the methods for managing Blob metadata
type BlobMetadataManagement interface {
// Create creates a new blob
Create(blob *Blob) (*Blob, error)
// GetByID retrieves blob by ID
GetByID(blobID string) (*Blob, error)
// UpdateByID updates a blob's metadata
UpdateByID(blobID string, updates *Blob) (*Blob, error)
// DeleteByID deletes a blob by ID
DeleteByID(blobID string) error
}
43 changes: 43 additions & 0 deletions internal/domain/blob/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package blob

import (
"crypto_vault_service/internal/domain/key"
"fmt"
"time"

"github.com/go-playground/validator/v10"
)

// Blob represents metadata on the actual blob being stored
type Blob struct {
ID string `gorm:"primaryKey" validate:"required,uuid4"` // ID is required and must be a valid UUID
UploadTime time.Time `validate:"required"` // UploadTime is required
UserID string `validate:"required,uuid4"` // UserID is required and must be a valid UUID
Name string `validate:"required,min=1,max=255"` // Name is required, and its length must be between 1 and 255 characters
Size int64 `validate:"required,min=1"` // Size must be greater than 0
Type string `validate:"required,min=1,max=50"` // Type is required, and its length must be between 1 and 50 characters
EncryptionAlgorithm string `validate:"omitempty,oneof=AES RSA ECDSA"` // EncryptionAlgorithm is optional and must be one of the listed algorithms
HashAlgorithm string `validate:"omitempty,oneof=SHA256 SHA512 MD5"` // HashAlgorithm is optional and must be one of the listed algorithms
IsEncrypted bool `validate:"-"` // IsEncrypted is required (true/false)
IsSigned bool `validate:"-"` // IsSigned is required (true/false)
CryptographicKey key.CryptographicKey `gorm:"foreignKey:KeyID" validate:"required"` // CryptographicKey is required
KeyID string `validate:"omitempty,uuid4"` // KeyID is optional and must be a valid UUID
}

// Validate for validating Blob struct
func (b *Blob) Validate() error {
// Initialize the validator
validate := validator.New()

// Validate the struct
err := validate.Struct(b)
if err != nil {
// If validation fails, return a formatted error
var validationErrors []string
for _, err := range err.(validator.ValidationErrors) {
validationErrors = append(validationErrors, fmt.Sprintf("Field: %s, Tag: %s", err.Field(), err.Tag()))
}
return fmt.Errorf("Validation failed: %v", validationErrors)
}
return nil // Return nil if validation passes
}
20 changes: 0 additions & 20 deletions internal/domain/contracts/blob_management.go

This file was deleted.

30 changes: 0 additions & 30 deletions internal/domain/contracts/key_management.go

This file was deleted.

29 changes: 0 additions & 29 deletions internal/domain/contracts/metadata_management.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
package contracts
package key

// Define KeyType as a custom type (based on int)
type KeyType int

// Enum-like values using iota
const (
AsymmetricPublic KeyType = iota
AsymmetricPrivate
Symmetric
)

// KeyManagement defines methods for managing cryptographic key operations.
type KeyManagement interface {
// Upload handles the upload of blobs from file paths.
// Returns the created Blobs metadata and any error encountered.
Upload(filePath []string) ([]*CryptographicKey, error)

// Download retrieves a cryptographic key by its ID and key type, returning the metadata and key data.
// Returns the key metadata, key data as a byte slice, and any error.
Download(keyId string, keyType KeyType) (*CryptographicKey, []byte, error)

// DeleteByID removes a cryptographic key by its ID.
// Returns any error encountered.
DeleteByID(keyId string) error
}

// CryptographicKeyMetadataManagement defines the methods for managing CryptographicKey metadata
type CryptographicKeyMetadataManagement interface {
// Create creates a new cryptographic key
Create(key *CryptographicKey) (*CryptographicKey, error)
// GetByID retrieves cryptographic key by ID
GetByID(keyID string) (*CryptographicKey, error)
// UpdateByID updates cryptographic key metadata
UpdateByID(keyID string, updates *CryptographicKey) (*CryptographicKey, error)
// DeleteByID deletes a cryptographic key by ID
DeleteByID(keyID string) error
}

// KeyOperations defines methods for key management, encryption, signing, and PKCS#11 operations.
type KeyOperations interface {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package model
package key

import (
"fmt"
Expand Down
42 changes: 0 additions & 42 deletions internal/domain/model/blob.go

This file was deleted.

File renamed without changes.
12 changes: 6 additions & 6 deletions internal/infrastructure/connector/az_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package connector
import (
"bytes"
"context"
"crypto_vault_service/internal/domain/model"
"crypto_vault_service/internal/domain/blob"
"fmt"
"log"
"os"
Expand All @@ -16,7 +16,7 @@ import (
// AzureBlobConnector is an interface for interacting with Azure Blob storage
type AzureBlobConnector interface {
// Upload uploads multiple files to Azure Blob Storage and returns their metadata.
Upload(filePaths []string) ([]*model.Blob, error)
Upload(filePaths []string) ([]*blob.Blob, error)
// Download retrieves a blob's content by its ID and name, and returns the data as a stream.
Download(blobId, blobName string) (*bytes.Buffer, error)
// Delete deletes a blob from Azure Blob Storage by its ID and Name, and returns any error encountered.
Expand Down Expand Up @@ -49,8 +49,8 @@ func NewAzureBlobConnector(connectionString string, containerName string) (*Azur
}

// Upload uploads multiple files to Azure Blob Storage and returns their metadata.
func (abc *AzureBlobConnectorImpl) Upload(filePaths []string) ([]*model.Blob, error) {
var blobs []*model.Blob
func (abc *AzureBlobConnectorImpl) Upload(filePaths []string) ([]*blob.Blob, error) {
var blobs []*blob.Blob
blobId := uuid.New().String()

// Iterate through all file paths and upload each file
Expand Down Expand Up @@ -86,7 +86,7 @@ func (abc *AzureBlobConnectorImpl) Upload(filePaths []string) ([]*model.Blob, er
fileExt := filepath.Ext(fileInfo.Name()) // Gets the file extension (e.g. ".txt", ".jpg")

// Create a Blob object for metadata
blob := &model.Blob{
blob := &blob.Blob{
ID: blobId,
Name: fileInfo.Name(),
Size: fileInfo.Size(),
Expand Down Expand Up @@ -115,7 +115,7 @@ func (abc *AzureBlobConnectorImpl) Upload(filePaths []string) ([]*model.Blob, er
}

// rollbackUploadedBlobs deletes the blobs that were uploaded successfully before the error occurred
func (abc *AzureBlobConnectorImpl) rollbackUploadedBlobs(blobs []*model.Blob) {
func (abc *AzureBlobConnectorImpl) rollbackUploadedBlobs(blobs []*blob.Blob) {
for _, blob := range blobs {
err := abc.Delete(blob.ID, blob.Name)
if err != nil {
Expand Down
18 changes: 9 additions & 9 deletions internal/persistence/repository/blob_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ package repository
import (
"fmt"

"crypto_vault_service/internal/domain/model"
"crypto_vault_service/internal/domain/blob"

"gorm.io/gorm"
)

// BlobRepository defines the interface for Blob-related operations
type BlobRepository interface {
Create(blob *model.Blob) error
GetById(blobID string) (*model.Blob, error)
UpdateById(blob *model.Blob) error
Create(blob *blob.Blob) error
GetById(blobID string) (*blob.Blob, error)
UpdateById(blob *blob.Blob) error
DeleteById(blobID string) error
}

Expand All @@ -22,7 +22,7 @@ type BlobRepositoryImpl struct {
}

// Create adds a new Blob to the database
func (r *BlobRepositoryImpl) Create(blob *model.Blob) error {
func (r *BlobRepositoryImpl) Create(blob *blob.Blob) error {
// Validate the Blob before saving
if err := blob.Validate(); err != nil {
return fmt.Errorf("validation error: %v", err)
Expand All @@ -36,8 +36,8 @@ func (r *BlobRepositoryImpl) Create(blob *model.Blob) error {
}

// GetById retrieves a Blob by its ID from the database
func (r *BlobRepositoryImpl) GetById(blobID string) (*model.Blob, error) {
var blob model.Blob
func (r *BlobRepositoryImpl) GetById(blobID string) (*blob.Blob, error) {
var blob blob.Blob
if err := r.DB.Where("id = ?", blobID).First(&blob).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("blob with ID %s not found", blobID)
Expand All @@ -48,7 +48,7 @@ func (r *BlobRepositoryImpl) GetById(blobID string) (*model.Blob, error) {
}

// UpdateById updates an existing Blob in the database
func (r *BlobRepositoryImpl) UpdateById(blob *model.Blob) error {
func (r *BlobRepositoryImpl) UpdateById(blob *blob.Blob) error {
// Validate the Blob before updating
if err := blob.Validate(); err != nil {
return fmt.Errorf("validation error: %v", err)
Expand All @@ -63,7 +63,7 @@ func (r *BlobRepositoryImpl) UpdateById(blob *model.Blob) error {

// DeleteById removes a Blob from the database by its ID
func (r *BlobRepositoryImpl) DeleteById(blobID string) error {
if err := r.DB.Where("id = ?", blobID).Delete(&model.Blob{}).Error; err != nil {
if err := r.DB.Where("id = ?", blobID).Delete(&blob.Blob{}).Error; err != nil {
return fmt.Errorf("failed to delete blob: %w", err)
}
return nil
Expand Down
Loading

0 comments on commit 86f4c62

Please sign in to comment.