Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,35 @@ http://localhost:8090/swagger-ui.html

## API Endpoints

### Document-management-service
### Document Management Service

```http
POST /documents - Upload a document
GET /documents - Retrieve a list of documents with pagination and filtering
DELETE /documents/{documentId} - Delete a document by its ID
#### Documents

POST /documents/{documentId}/versions - Upload a document version
DELETE /documents/{documentId}/versions/{versionId} - Delete certain document version
GET /documents/{documentId}/versions/{versionId}/download - Download certain document version
```
| Method | Endpoint | Description |
|--------|------------------------|------------------------------------------------------------|
| POST | `/documents` | Upload a new document (metadata + file) |
| GET | `/documents` | Retrieve a list of documents with pagination and filters |
| DELETE | `/documents/{documentId}` | Delete a document along with all its versions |

---

#### Document Versions

| Method | Endpoint | Description |
|--------|---------------------------------------------------------|------------------------------------------------------------|
| POST | `/documents/{documentId}/versions` | Upload a new version for the specified document |
| DELETE | `/documents/{documentId}/versions/{versionId}` | Delete a specific version of a document |
| GET | `/documents/{documentId}/versions/{versionId}/download` | Download a specific version of a document |

---

#### Signatures and Hashes (used by Document Signing Service)

| Method | Endpoint | Description |
|--------|------------------------------------------------------------|------------------------------------------------------------|
| GET | `/documents/{documentId}/versions/{versionId}/hash` | Retrieve the Base64-encoded hash of the document version |
| POST | `/documents/{documentId}/versions/{versionId}/signatures` | Save a digital signature for the given document version |
| | | _Invoked from Document Signing Service (DSS) via WebClient_ |

## CI Pipeline

Expand Down
36 changes: 27 additions & 9 deletions README_RUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,35 @@ http://localhost:8090/swagger-ui.html

## API-эндпоинты

### Document-management-service
### Document Management Service

```http
POST /documents - Загрузить документ
GET /documents - Получить список документов с пагинацией и фильтрацией
DELETE /documents/{documentId} - Удалить документ по его ID
#### Документы

POST /documents/{documentId}/versions - Загрузить версию документа
DELETE /documents/{documentId}/versions/{versionId} - Удалить версию документа
GET /documents/{documentId}/versions/{versionId}/download - Скачать документ определенной версии
```
| Метод | Endpoint | Описание |
|-------|---------------------|------------------------------------------------------|
| POST | `/documents` | Загрузить новый документ (метаданные + файл) |
| GET | `/documents` | Получить список документов с пагинацией и фильтрацией|
| DELETE| `/documents/{documentId}` | Удалить документ и все его версии |

---

#### Версии документов

| Метод | Endpoint | Описание |
|-------|-------------------------------------------------|------------------------------------|
| POST | `/documents/{documentId}/versions` | Загрузить новую версию документа |
| DELETE| `/documents/{documentId}/versions/{versionId}` | Удалить конкретную версию документа |
| GET | `/documents/{documentId}/versions/{versionId}/download`| Скачать указанную версию документа |

---

#### Подписи и хэши (используется Document Signing Service)

| Метод | Endpoint | Описание |
|-------|-----------------------------------------------------------|--------------------------------------------------------------------------|
| GET | `/documents/{documentId}/versions/{versionId}/hash` | Получить Base64-хэш содержимого версии документа |
| POST | `/documents/{documentId}/versions/{versionId}/signatures` | Сохранить электронную подпись к версии документа |
| | | _Вызывается из DSS через WebClient_ |

## CI Pipeline

Expand Down
5 changes: 5 additions & 0 deletions document-management-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ FROM maven:3.6.3-jdk-11-slim AS build

WORKDIR /build

WORKDIR /build/document-api-dto
COPY /document-api-dto/pom.xml /build/document-api-dto
COPY /document-api-dto/src /build/document-api-dto/src
RUN mvn -B clean install -DskipTests

WORKDIR /build/logging-starter
COPY /logging-starter/pom.xml /build/logging-starter
COPY /logging-starter/src /build/logging-starter/src
Expand Down
5 changes: 5 additions & 0 deletions document-management-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@
<artifactId>dotenv-java</artifactId>
<version>${dotenv-java.version}</version>
</dependency>
<dependency>
<groupId>com.github.tennyros</groupId>
<artifactId>document-api-dto</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.tennyros</groupId>
<artifactId>logging-starter</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.github.tennyros.management.controller;

import com.github.tennyros.dto.DocumentSignatureResponse;
import com.github.tennyros.dto.SaveSignatureRequest;
import com.github.tennyros.management.service.DocumentSignatureService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/documents/{documentId}/versions/{versionId}/signatures")
public class DocumentSignatureController {

private final DocumentSignatureService documentSignatureService;

@PostMapping
public ResponseEntity<DocumentSignatureResponse> saveSignature(@PathVariable Long documentId,
@PathVariable Long versionId,
@RequestBody @Valid SaveSignatureRequest request) {
Long savedSignatureId = documentSignatureService.saveSignature(documentId, versionId, request);
return ResponseEntity.ok(new DocumentSignatureResponse(savedSignatureId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.tennyros.management.controller;

import com.github.tennyros.dto.DocumentHashResponse;
import com.github.tennyros.management.dto.version.response.DocumentVersionResponse;
import com.github.tennyros.management.service.DocumentVersionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/documents/{documentId}/versions/{versionId}/hash")
public class DocumentVersionHashController {

private final DocumentVersionService documentVersionService;

@GetMapping
public ResponseEntity<DocumentHashResponse> getHash(@PathVariable Long documentId, @PathVariable Long versionId) {
DocumentVersionResponse documentVersion = documentVersionService.getDocumentVersion(documentId, versionId);
DocumentHashResponse response = DocumentHashResponse.builder()
.documentId(documentId)
.versionId(versionId)
.hash(documentVersion.getHash())
.build();

return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;

Expand All @@ -25,12 +26,15 @@ public class DocumentFilter {
@Size(max = 100, message = "Content type length must be less than or equal to 100 characters")
private String contentType;

@NotNull(message = "Min size number is required")
@Min(value = 0, message = "Min size must be positive")
private Long minSize;

@NotNull(message = "Max size number is required")
@Min(value = 0, message = "Max size must be positive")
private Long maxSize;

@Min(value = 0, message = "Version number must be positive")
@NotNull(message = "Version number is required")
@Min(value = 1, message = "Version number must be positive")
private Long versionNumber;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
public class DocumentResponse {

private Long id;

private String title;

private String description;

private LocalDateTime createdAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@
public class PageResponse<T> {

private List<T> content;

private int page;

private int size;

private long totalElements;

private int totalPages;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,12 @@
public class DocumentVersionResponse {

private Long id;

private Long documentId;

private long versionNumber;

private String filename;

private String contentType;

private long size;

private String storageKey;

private LocalDateTime uploadedAt;
private String hash;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.github.tennyros.management.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.time.LocalDateTime;

@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "document_signature")
public class DocumentSignature {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "document_version_id")
private DocumentVersion documentVersion;

@Lob
private byte[] signature;

private String signatureAlgorithm;
private String certificateSubject;
private String certificateIssuer;
private String certificateSerialNumber;
private LocalDateTime signedAt;
private String signedBy;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
Expand All @@ -41,12 +46,14 @@ public class DocumentVersion {

private LocalDateTime uploadedAt;

private String hash;

@ManyToOne
@JoinColumn(name = "document_id")
private Document document;

private String metadataId;

@Lob
private byte[] signature;
@OneToMany(mappedBy = "documentVersion", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<DocumentSignature> signatures = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.github.tennyros.management.repository.jpa;

import com.github.tennyros.management.entity.DocumentSignature;
import org.springframework.data.jpa.repository.JpaRepository;

public interface DocumentSignatureRepository extends JpaRepository<DocumentSignature, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.github.tennyros.management.service;

import com.github.tennyros.dto.SaveSignatureRequest;

public interface DocumentSignatureService {

Long saveSignature(Long documentId, Long versionId, SaveSignatureRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.github.tennyros.management.service;

import java.io.InputStream;

public interface HashService {

String calculateSHA256(InputStream inputStream);
}
Loading
Loading