Skip to content

Commit 3e85f8e

Browse files
committed
Admin Product Add,Edit,Delete.Update, Pagination.
1 parent b760d2f commit 3e85f8e

File tree

35 files changed

+977
-365
lines changed

35 files changed

+977
-365
lines changed

bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/impl/UserServiceImpl.java

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.devd.spring.bookstoreaccountservice.repository.UserRepository;
66
import com.devd.spring.bookstoreaccountservice.repository.dao.Role;
77
import com.devd.spring.bookstoreaccountservice.repository.dao.User;
8-
import com.devd.spring.bookstoreaccountservice.service.RoleService;
98
import com.devd.spring.bookstoreaccountservice.service.UserRoleService;
109
import com.devd.spring.bookstoreaccountservice.service.UserService;
1110
import com.devd.spring.bookstoreaccountservice.web.CreateUserRequest;

bookstore-api-gateway-service/src/main/resources/application.yml

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ spring:
1313
sleuth:
1414
sampler:
1515
probability: 1.0
16+
servlet:
17+
multipart:
18+
max-file-size: 10MB
19+
max-request-size: 10MB
1620

1721
zuul:
1822
sensitiveHeaders:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.devd.spring.bookstorecatalogservice.controller;
2+
3+
import com.devd.spring.bookstorecatalogservice.repository.ImageRepository;
4+
import com.devd.spring.bookstorecatalogservice.repository.dao.ImageModel;
5+
import com.devd.spring.bookstorecommons.exception.RunTimeExceptionPlaceHolder;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.core.io.ByteArrayResource;
8+
import org.springframework.core.io.Resource;
9+
import org.springframework.http.HttpStatus;
10+
import org.springframework.http.MediaType;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.web.bind.annotation.GetMapping;
13+
import org.springframework.web.bind.annotation.PathVariable;
14+
import org.springframework.web.bind.annotation.PostMapping;
15+
import org.springframework.web.bind.annotation.RequestMapping;
16+
import org.springframework.web.bind.annotation.RequestParam;
17+
import org.springframework.web.bind.annotation.RestController;
18+
import org.springframework.web.multipart.MultipartFile;
19+
20+
import java.io.ByteArrayOutputStream;
21+
import java.io.IOException;
22+
import java.util.Base64;
23+
import java.util.HashMap;
24+
import java.util.Map;
25+
import java.util.Optional;
26+
import java.util.zip.DataFormatException;
27+
import java.util.zip.Deflater;
28+
import java.util.zip.Inflater;
29+
30+
/**
31+
* @author Devaraj Reddy - 21-Dec-2020
32+
*/
33+
@RestController
34+
@RequestMapping(path = "image")
35+
public class ImageUploadController {
36+
@Autowired
37+
ImageRepository imageRepository;
38+
39+
@PostMapping("/upload")
40+
public ResponseEntity<?> uploadImage(@RequestParam("imageFile") MultipartFile file) throws IOException {
41+
System.out.println("Original Image Byte Size - " + file.getBytes().length);
42+
ImageModel img = new ImageModel(file.getOriginalFilename(), file.getContentType(),
43+
compressBytes(file.getBytes()));
44+
ImageModel savedImage = imageRepository.save(img);
45+
Map<String, String> response = new HashMap<>();
46+
response.put("imageId", savedImage.getImageId());
47+
return ResponseEntity.status(HttpStatus.OK).body(response);
48+
}
49+
50+
@GetMapping(path = "/{imageId}")
51+
public ResponseEntity<?> getImage(@PathVariable String imageId) {
52+
try {
53+
final Optional<ImageModel> retrievedImage = imageRepository.findByImageId(imageId);
54+
if (!retrievedImage.isPresent()) {
55+
throw new RunTimeExceptionPlaceHolder("Image doesn't exist!");
56+
}
57+
ByteArrayResource resource = new ByteArrayResource(decompressBytes(retrievedImage.get().getPicByte()));
58+
String encodedString = Base64.getEncoder().encodeToString(resource.getByteArray());
59+
60+
Map<String, String> response = new HashMap<>();
61+
response.put("imageBase64", encodedString);
62+
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(encodedString);
63+
} catch (Exception e) {
64+
throw new RunTimeExceptionPlaceHolder("Unable to get image");
65+
}
66+
}
67+
68+
// compress the image bytes before storing it in the database
69+
public static byte[] compressBytes(byte[] data) {
70+
Deflater deflater = new Deflater();
71+
deflater.setInput(data);
72+
deflater.finish();
73+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
74+
byte[] buffer = new byte[1024];
75+
while (!deflater.finished()) {
76+
int count = deflater.deflate(buffer);
77+
outputStream.write(buffer, 0, count);
78+
}
79+
try {
80+
outputStream.close();
81+
} catch (IOException e) {
82+
}
83+
System.out.println("Compressed Image Byte Size - " + outputStream.toByteArray().length);
84+
return outputStream.toByteArray();
85+
}
86+
87+
// uncompress the image bytes before returning it to the angular application
88+
public static byte[] decompressBytes(byte[] data) {
89+
Inflater inflater = new Inflater();
90+
inflater.setInput(data);
91+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
92+
byte[] buffer = new byte[1024];
93+
try {
94+
while (!inflater.finished()) {
95+
int count = inflater.inflate(buffer);
96+
outputStream.write(buffer, 0, count);
97+
}
98+
outputStream.close();
99+
} catch (IOException ioe) {
100+
} catch (DataFormatException e) {
101+
}
102+
return outputStream.toByteArray();
103+
}
104+
}

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/ProductController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public ResponseEntity<?> deleteProductCategory(@PathVariable("productId") String
7070

7171
@PutMapping("/product")
7272
@PreAuthorize("hasAuthority('ADMIN_USER')")
73-
public ResponseEntity<?> updateProductCategory(@RequestBody @Valid UpdateProductRequest updateProductRequest) {
73+
public ResponseEntity<?> updateProduct(@RequestBody @Valid UpdateProductRequest updateProductRequest) {
7474

7575
productService.updateProduct(updateProductRequest);
7676

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.devd.spring.bookstorecatalogservice.repository;
2+
3+
import com.devd.spring.bookstorecatalogservice.repository.dao.ImageModel;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
6+
import java.util.Optional;
7+
8+
/**
9+
* @author Devaraj Reddy - 21-Dec-2020
10+
*/
11+
public interface ImageRepository extends JpaRepository<ImageModel, Long> {
12+
Optional<ImageModel> findByName(String name);
13+
14+
Optional<ImageModel> findByImageId(String imageId);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.devd.spring.bookstorecatalogservice.repository.dao;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
import org.hibernate.annotations.GenericGenerator;
8+
9+
import javax.persistence.Column;
10+
import javax.persistence.Entity;
11+
import javax.persistence.GeneratedValue;
12+
import javax.persistence.Id;
13+
import javax.persistence.Table;
14+
15+
/**
16+
* @author Devaraj Reddy - 21-Dec-2020
17+
*/
18+
@Entity
19+
@Table(name = "IMAGE_TABLE")
20+
@Builder
21+
@Data
22+
@AllArgsConstructor
23+
@NoArgsConstructor
24+
public class ImageModel {
25+
26+
public ImageModel(String name, String type, byte[] picByte) {
27+
this.name = name;
28+
this.type = type;
29+
this.picByte = picByte;
30+
}
31+
32+
@Id
33+
@GeneratedValue(generator = "uuid")
34+
@GenericGenerator(name = "uuid", strategy = "uuid2")
35+
@Column(name = "IMAGE_ID", updatable = false, nullable = false)
36+
private String imageId;
37+
38+
@Column(name = "NAME")
39+
private String name;
40+
41+
@Column(name = "TYPE")
42+
private String type;
43+
44+
//image bytes can have large lengths so we specify a value
45+
//which is more than the default length for picByte column
46+
@Column(name = "PIC_BYTES", length = 1000)
47+
private byte[] picByte;
48+
49+
}

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/repository/dao/Product.java

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public class Product extends DateAudit {
4545
private String description;
4646
private double price;
4747

48+
@Column(name = "PRODUCT_IMAGE_ID")
49+
private String imageId;
50+
4851
@ManyToOne
4952
@JoinColumn(name = "PRODUCT_CATEGORY_ID")
5053
private ProductCategory productCategory;

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/service/impl/ProductCategoryServiceImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void updateProductCategory(UpdateProductCategoryRequest updateProductCate
6868
.description(updateProductCategoryRequest.getDescription())
6969
.build();
7070

71-
productCategory.setCreated_at(getProductCategory.getCreated_at());
71+
productCategory.setCreatedAt(getProductCategory.getCreatedAt());
7272

7373
productCategoryRepository.save(productCategory);
7474

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/service/impl/ProductServiceImpl.java

+33-16
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public String createProduct(@Valid CreateProductRequest createProductRequest) {
5959
.availableItemCount(createProductRequest.getAvailableItemCount())
6060
.price(createProductRequest.getPrice())
6161
.productCategory(productCategory)
62+
.imageId(createProductRequest.getImageId())
6263
.build();
6364

6465

@@ -99,30 +100,46 @@ public void deleteProduct(String productId) {
99100
@Override
100101
public void updateProduct(UpdateProductRequest updateProductRequest) {
101102

102-
Optional<ProductCategory> productCategoryOptional =
103-
productCategoryRepository.findById(updateProductRequest.getProductCategoryId());
104-
105-
//check weather product category exists
106-
ProductCategory productCategory = productCategoryOptional.orElseThrow(() -> new RuntimeException("ProductCategory doesn't exist!"));
107-
108103
Optional<Product> productOptional =
109104
productRepository.findById(updateProductRequest.getProductId());
110105

111106
//check weather product exists
112107
final Product productExisting = productOptional.orElseThrow(() -> new RuntimeException("Product Id doesn't exist!"));
113108

114-
Product product = Product.builder()
115-
.productId(updateProductRequest.getProductId())
116-
.productName(updateProductRequest.getProductName())
117-
.description(updateProductRequest.getDescription())
118-
.availableItemCount(updateProductRequest.getAvailableItemCount())
119-
.price(updateProductRequest.getPrice())
120-
.productCategory(productCategory)
121-
.build();
109+
productExisting.setProductId(updateProductRequest.getProductId());
110+
111+
if (updateProductRequest.getProductName() != null) {
112+
productExisting.setProductName(updateProductRequest.getProductName());
113+
}
114+
115+
if (updateProductRequest.getDescription() != null) {
116+
productExisting.setDescription(updateProductRequest.getDescription());
117+
}
118+
119+
if (updateProductRequest.getPrice() != null) {
120+
productExisting.setPrice(updateProductRequest.getPrice());
121+
}
122+
123+
if (updateProductRequest.getImageId() != null) {
124+
productExisting.setImageId(updateProductRequest.getImageId());
125+
}
126+
127+
if (updateProductRequest.getProductCategoryId() != null) {
128+
Optional<ProductCategory> productCategoryOptional =
129+
productCategoryRepository.findById(updateProductRequest.getProductCategoryId());
130+
131+
//check weather product category exists
132+
ProductCategory productCategory = productCategoryOptional.orElseThrow(() -> new RuntimeException("ProductCategory doesn't exist!"));
133+
productExisting.setProductCategory(productCategory);
134+
}
135+
136+
if (updateProductRequest.getAvailableItemCount() != null) {
137+
productExisting.setAvailableItemCount(updateProductRequest.getAvailableItemCount());
138+
}
122139

123-
product.setCreated_at(productExisting.getCreated_at());
140+
productExisting.setCreatedAt(productExisting.getCreatedAt());
124141

125-
productRepository.save(product);
142+
productRepository.save(productExisting);
126143
}
127144

128145
@Override

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/CreateProductRequest.java

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public class CreateProductRequest {
2626
@Min(value = 0)
2727
private double price;
2828

29+
private String imageId;
30+
2931
@NotNull(message = "productCategoryId should not be null!")
3032
@NotEmpty(message = "productCategoryId should not be empty!")
3133
private String productCategoryId;

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/ProductResponse.java

+1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ public class ProductResponse {
2020
private int availableItemCount;
2121
private Double averageRating;
2222
private int noOfRatings;
23+
private String imageId;
2324

2425
}

bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/UpdateProductRequest.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,17 @@ public class UpdateProductRequest {
2121
@NotEmpty(message = "productId should not be empty!")
2222
private String productId;
2323

24-
@NotNull(message = "productName should not be null!")
25-
@NotEmpty(message = "productName should not be empty!")
2624
private String productName;
2725

2826
private String description;
2927

3028
@Min(value = 0)
31-
private double price;
29+
private Double price;
30+
31+
private String imageId;
3232

33-
@NotNull(message = "productCategoryId should not be null!")
34-
@NotEmpty(message = "productCategoryId should not be empty!")
3533
private String productCategoryId;
3634

37-
private int availableItemCount;
35+
private Integer availableItemCount;
3836

3937
}

bookstore-catalog-service/src/main/resources/application.yml

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ spring:
2525
allow-bean-definition-overriding: true
2626
hateoas:
2727
use-hal-as-default-json-media-type: false
28+
servlet:
29+
multipart:
30+
max-file-size: 10MB
31+
max-request-size: 10MB
2832

2933
logging:
3034
level:

bookstore-catalog-service/src/main/resources/db/migration/V1__catalog_service_schema.sql

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ create table PRODUCT (
55
price double not null,
66
product_name varchar(255) not null,
77
product_category_id varchar(255),
8+
product_image_id varchar(255),
89
CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
910
UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
1011
primary key (product_id)
@@ -35,3 +36,13 @@ create table REVIEW (
3536
UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
3637
primary key (review_id)
3738
);
39+
40+
create table IMAGE_TABLE(
41+
image_id varchar(255) not null,
42+
type varchar(10),
43+
name varchar(255),
44+
PIC_BYTES varchar,
45+
CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
46+
UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
47+
primary key (image_id)
48+
)

0 commit comments

Comments
 (0)