Skip to content

Commit 4c00c63

Browse files
feat(api): added scan api & implementation
1 parent d91575d commit 4c00c63

File tree

15 files changed

+256
-32
lines changed

15 files changed

+256
-32
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,6 @@ jobs:
8787
- uses: ncipollo/release-action@v1
8888
with:
8989
artifacts: "dist/*"
90-
tag: 0.0.1-SNAPSHOT
90+
tag: 0.1.0
9191
body: |
9292
Release ${{ github.ref }}

build.gradle

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010
}
1111

1212
group = 'com.ssegning.lynx'
13-
version = '0.0.1-SNAPSHOT'
13+
version = '0.1.0'
1414

1515
java {
1616
sourceCompatibility = '21'
@@ -31,6 +31,7 @@ ext {
3131
}
3232

3333
dependencies {
34+
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
3435
implementation 'org.springframework.boot:spring-boot-starter-actuator'
3536
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
3637
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
@@ -40,9 +41,12 @@ dependencies {
4041
implementation 'org.springframework.boot:spring-boot-starter-websocket'
4142
implementation 'io.sentry:sentry-spring-boot-starter-jakarta'
4243
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
44+
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
45+
runtimeOnly 'com.h2database:h2'
4346
compileOnly 'org.projectlombok:lombok'
4447
developmentOnly 'org.springframework.boot:spring-boot-devtools'
4548
annotationProcessor 'org.projectlombok:lombok'
49+
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
4650
testImplementation 'org.springframework.boot:spring-boot-starter-test'
4751
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
4852
testImplementation 'org.springframework.security:spring-security-test'

frontend

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.ssegning.lynx.local;
2+
3+
import org.springframework.boot.autoconfigure.domain.EntityScan;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
6+
7+
@EntityScan
8+
@Configuration
9+
@EnableJpaRepositories
10+
public class JpaConfig {
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.ssegning.lynx.local.domain;
2+
3+
import jakarta.persistence.*;
4+
import lombok.Data;
5+
import org.springframework.data.annotation.CreatedDate;
6+
import org.springframework.data.annotation.LastModifiedDate;
7+
8+
import java.util.Map;
9+
import java.util.UUID;
10+
11+
@Data
12+
@Entity
13+
@Table(name = "scans")
14+
public class ScanEntity {
15+
16+
@Id
17+
@Column
18+
private UUID id;
19+
20+
@Column(name = "created_at")
21+
@CreatedDate
22+
private String createdAt;
23+
24+
@Column(name = "updated_at")
25+
@LastModifiedDate
26+
private String updatedAt;
27+
28+
@Column(name = "title")
29+
private String title;
30+
31+
@ElementCollection
32+
@CollectionTable(name = "scan_meta_data", joinColumns = @JoinColumn(name = "scan_id"))
33+
private Map<String, String> metaData;
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.ssegning.lynx.local.mapper;
2+
3+
import com.ssegning.lynx.local.domain.ScanEntity;
4+
import com.ssegning.lynx.local.service.ScanFactory;
5+
import com.ssegning.lynx.lynxbackend.model.Scan;
6+
import org.mapstruct.Mapper;
7+
import org.mapstruct.Mapping;
8+
import org.mapstruct.MappingConstants;
9+
10+
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = {UuidMapper.class, ScanFactory.class})
11+
public interface ScanMapper {
12+
@Mapping(target = "id", ignore = true)
13+
ScanEntity map(Scan scan);
14+
15+
Scan map(ScanEntity scan);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.ssegning.lynx.local.mapper;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
import java.util.UUID;
6+
7+
@Component
8+
public class UuidMapper {
9+
public String map(UUID value) {
10+
if (value == null) {
11+
return null;
12+
}
13+
14+
return value.toString();
15+
}
16+
17+
public UUID map(String value) {
18+
if (value == null) {
19+
return null;
20+
}
21+
22+
return UUID.fromString(value);
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.ssegning.lynx.local.repo;
2+
3+
import com.ssegning.lynx.local.domain.ScanEntity;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
import java.util.UUID;
8+
9+
@Repository
10+
public interface ScanRepo extends JpaRepository<ScanEntity, UUID> {
11+
}

src/main/java/com/ssegning/lynx/local/LocalFSUpload.java src/main/java/com/ssegning/lynx/local/service/LocalFSUploadService.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.ssegning.lynx.local;
1+
package com.ssegning.lynx.local.service;
22

33
import com.ssegning.lynx.lynxbackend.exceptions.StorageException;
44
import com.ssegning.lynx.lynxbackend.exceptions.StorageFileNotFoundException;
@@ -21,7 +21,7 @@
2121

2222
@Service
2323
@RequiredArgsConstructor
24-
public class LocalFSUpload implements FileUpload {
24+
public class LocalFSUploadService implements FileUpload {
2525

2626
@Value("${file.upload-dir}")
2727
private Path rootLocation;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.ssegning.lynx.local.service;
2+
3+
import com.ssegning.lynx.local.repo.ScanRepo;
4+
import com.ssegning.lynx.local.mapper.UuidMapper;
5+
import com.ssegning.lynx.local.domain.ScanEntity;
6+
import com.ssegning.lynx.lynxbackend.model.Scan;
7+
import lombok.RequiredArgsConstructor;
8+
import org.mapstruct.ObjectFactory;
9+
import org.springframework.stereotype.Component;
10+
11+
@Component
12+
@RequiredArgsConstructor
13+
public class ScanFactory {
14+
private final ScanRepo repo;
15+
private final UuidMapper uuidMapper;
16+
17+
@ObjectFactory
18+
public ScanEntity factory(Scan scan) {
19+
var id = uuidMapper.map(scan.getId());
20+
if (id == null) {
21+
return new ScanEntity();
22+
}
23+
24+
return repo.getReferenceById(id);
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.ssegning.lynx.local.service;
2+
3+
import com.ssegning.lynx.local.mapper.ScanMapper;
4+
import com.ssegning.lynx.local.repo.ScanRepo;
5+
import com.ssegning.lynx.local.mapper.UuidMapper;
6+
import com.ssegning.lynx.lynxbackend.model.Scan;
7+
import com.ssegning.lynx.lynxbackend.service.ScanService;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.data.domain.PageRequest;
10+
import org.springframework.stereotype.Service;
11+
12+
import java.math.BigDecimal;
13+
import java.util.List;
14+
15+
@Service
16+
@RequiredArgsConstructor
17+
public class ScanServiceImpl implements ScanService {
18+
private final ScanRepo repo;
19+
private final ScanMapper mapper;
20+
private final UuidMapper uuidMapper;
21+
22+
@Override
23+
public Scan createScan(Scan scan) {
24+
var entity = mapper.map(scan);
25+
var saved = repo.save(entity);
26+
return mapper.map(saved);
27+
}
28+
29+
@Override
30+
public Scan updateScan(String scanId, Scan scan) {
31+
scan.setId(scanId);
32+
var entity = mapper.map(scan);
33+
var saved = repo.save(entity);
34+
return mapper.map(saved);
35+
}
36+
37+
@Override
38+
public Scan getScan(String scanId) {
39+
var id = uuidMapper.map(scanId);
40+
var saved = repo.getReferenceById(id);
41+
return mapper.map(saved);
42+
}
43+
44+
@Override
45+
public void deleteScan(String scanId) {
46+
var id = uuidMapper.map(scanId);
47+
repo.deleteById(id);
48+
}
49+
50+
@Override
51+
public List<Scan> getScans(BigDecimal page, BigDecimal size) {
52+
var pageRequest = PageRequest.of(page.intValue(), size.intValue());
53+
var entities = repo.findAll(pageRequest).getContent();
54+
return entities.stream().map(mapper::map).toList();
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.ssegning.lynx.lynxbackend.controller;
2+
3+
import com.ssegning.lynx.lynxbackend.api.ScanApi;
4+
import com.ssegning.lynx.lynxbackend.model.Scan;
5+
import com.ssegning.lynx.lynxbackend.service.ScanService;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
import java.math.BigDecimal;
11+
import java.util.List;
12+
import java.util.Optional;
13+
14+
@RestController
15+
@RequestMapping
16+
@RequiredArgsConstructor
17+
public class ScanApiImpl implements ScanApi {
18+
private final ScanService scanService;
19+
20+
@Override
21+
public Scan createScan(Scan scan) {
22+
return scanService.createScan(scan);
23+
}
24+
25+
@Override
26+
public void deleteScan(String scanId) {
27+
scanService.deleteScan(scanId);
28+
}
29+
30+
@Override
31+
public Scan getScan(String scanId) {
32+
return scanService.getScan(scanId);
33+
}
34+
35+
@Override
36+
public List<Scan> getScans(Optional<BigDecimal> page, Optional<BigDecimal> size) {
37+
return scanService.getScans(page.orElse(BigDecimal.ZERO), size.orElse(BigDecimal.TEN));
38+
}
39+
40+
@Override
41+
public Scan updateScan(String scanId, Scan scan) {
42+
return scanService.updateScan(scanId, scan);
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.ssegning.lynx.lynxbackend.service;
2+
3+
import com.ssegning.lynx.lynxbackend.model.Scan;
4+
5+
import java.math.BigDecimal;
6+
import java.util.List;
7+
8+
public interface ScanService {
9+
Scan createScan(Scan scan);
10+
11+
Scan updateScan(String scanId, Scan scan);
12+
13+
Scan getScan(String scanId);
14+
15+
void deleteScan(String scanId);
16+
17+
List<Scan> getScans(BigDecimal page, BigDecimal size);
18+
}

src/main/resources/application-local.yaml

+7-1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ spring:
127127
- org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration
128128
- org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration
129129
- org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration
130+
jpa:
131+
database: h2
132+
generate-ddl: true
133+
open-in-view: false
134+
datasource:
135+
url: jdbc:h2:file:./tmp/h2db
130136

131137
file:
132-
upload-dir: ./tmp
138+
upload-dir: ./tmp

src/test/java/com/ssegning/lynx/mongo/TestLynxBackendApplication.java

-26
This file was deleted.

0 commit comments

Comments
 (0)