Skip to content
This repository has been archived by the owner on Feb 13, 2023. It is now read-only.

Events integration #64

Merged
merged 13 commits into from
Dec 9, 2017
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ fabric.properties
hs_err_pid*

application.properties
application.yml
.gradle/
.idea/
build/
src/main/resources/templates/fragments/product/
config/oidc-client-registration.json
*.iml
7 changes: 6 additions & 1 deletion config/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ security.basic.enabled: false
flyway.enabled: false

# Serve connect
server.port: 9000
server:
context-path: /payments/

#Spring Boot Actuator endpoint settings
management:
Expand Down Expand Up @@ -56,3 +57,7 @@ payments:
admin:
username: admin
password: password

events:
username: CH Events
password: secret
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public interface ProductService {

Product getProductById(Integer productId);

Product getProductByKey(String key);

Set<Product> getProductByCommittee(CommitteeEnum committeeEnum, int year);

boolean isProductAvailable(Integer productId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ch.wisv.payments.admin.products.request.ProductRequest;
import ch.wisv.payments.exception.ProductGroupInUseException;
import ch.wisv.payments.exception.ProductInUseException;
import ch.wisv.payments.exception.ProductNotFoundException;
import ch.wisv.payments.model.*;
import ch.wisv.payments.rest.OrderService;
import ch.wisv.payments.rest.repository.ProductGroupRepository;
Expand Down Expand Up @@ -116,6 +117,11 @@ public Product getProductById(Integer productId) {
return productRepository.findOne(productId);
}

@Override
public Product getProductByKey(String key) {
return productRepository.findOneByKey(key).orElseThrow(ProductNotFoundException::new);
}

@Override
public Set<Product> getProductByCommittee(CommitteeEnum committeeEnum, int year) {
Committee committee = committeeService.getCommittee(committeeEnum, year);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/ch/wisv/payments/model/CommitteeEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public enum CommitteeEnum {
WIFI("WiFi"),
W3CIE("W3Cie"),
WIEWIE("WIEWIE"),
WOCKY("Wocky!");
WOCKY("Wocky!"),
BESTUUR("Bestuur");

private final String name;

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/ch/wisv/payments/model/eventsync/EventsSync.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ch.wisv.payments.model.eventsync;

import lombok.Data;
import lombok.Getter;

@Data
class EventsSync {

@Getter
private String trigger;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ch.wisv.payments.model.eventsync;

public enum EventsSyncEnum {

PRODUCT_CREATE_EDIT,
PRODUCT_DELETE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ch.wisv.payments.model.eventsync;

import lombok.Data;
import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = false)
@Data
public class ProductEventsSync extends EventsSync {

/**
* Price of the product.
*/
private Double price;

/**
* Description of the product.
*/
private String description;

/**
* Title of the product.
*/
private String title;

/**
* UUID of the product.
*/
private String key;

/**
* Enum string of the organizing Committee.
*/
private String organizedBy;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ch.wisv.payments.rest.eventsync;

import ch.wisv.payments.model.eventsync.ProductEventsSync;

public interface EventsSyncProductService {

/**
* Create a Product from a ProductEventsSync model.
*
* @param productEventsSync of type ProductEventsSync
*/
void createProduct(ProductEventsSync productEventsSync);

/**
* Edit a Product from a ProductEventsSync model.
*
* @param productEventsSync of type ProductEventsSync
*/
void editProduct(ProductEventsSync productEventsSync);

/**
* Delete a Product from a ProductEventsSync model.
*
* @param productEventsSync of type ProductEventsSync
*/
void deleteProduct(ProductEventsSync productEventsSync);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package ch.wisv.payments.rest.eventsync;

import ch.wisv.payments.admin.committees.CommitteeRepository;
import ch.wisv.payments.exception.ProductNotFoundException;
import ch.wisv.payments.model.Committee;
import ch.wisv.payments.model.CommitteeEnum;
import ch.wisv.payments.model.Product;
import ch.wisv.payments.model.eventsync.ProductEventsSync;
import ch.wisv.payments.rest.repository.ProductRepository;
import org.springframework.stereotype.Service;

@Service
public class EventsSyncProductServiceImpl implements EventsSyncProductService {

/**
* ProductRepository.
*/
private final ProductRepository productRepository;

/**
* CommitteeRepository.
*/
private final CommitteeRepository committeeRepository;

/**
* Constructor.
*
* @param productRepository of type ProductRepository
* @param committeeRepository of type CommitteeRepository
*/
public EventsSyncProductServiceImpl(ProductRepository productRepository, CommitteeRepository committeeRepository) {
this.productRepository = productRepository;
this.committeeRepository = committeeRepository;
}

/**
* @param productEventsSync of type ProductEventsSync
*/
@Override
public void createProduct(ProductEventsSync productEventsSync) {
Product product = new Product();
product.setKey(productEventsSync.getKey());

this.changeProductValues(product, productEventsSync);

productRepository.save(product);
}

/**
* @param productEventsSync of type ProductEventsSync
*/
@Override
public void editProduct(ProductEventsSync productEventsSync) {
Product product = this.getProductByKey(productEventsSync.getKey());

this.changeProductValues(product, productEventsSync);

productRepository.save(product);
}

/**
* Change the Product values using a ProductEventsSync model.
*
* @param product of type Product.
* @param productEventsSync of type ProductEventsSync.
*/
private void changeProductValues(Product product, ProductEventsSync productEventsSync) {
if (product.getCommittee() == null || product.getCommittee().toString().equals(productEventsSync.getOrganizedBy())) {
this.changeProductCommittee(product, productEventsSync);
}

product.setDescription(productEventsSync.getDescription());
product.setName(productEventsSync.getTitle());
product.setPrice(productEventsSync.getPrice().floatValue());
}

/**
* Change the Committee of Product.
*
* @param product of type Product
* @param productEventsSync of type ProductEventsSync
*/
private void changeProductCommittee(Product product, ProductEventsSync productEventsSync) {
CommitteeEnum committeeEnum = CommitteeEnum.valueOf(productEventsSync.getOrganizedBy());
int year = 2017;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be dynamic!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue #65


Committee committee = committeeRepository.findOneByNameAndYear(committeeEnum, year)
.orElse(new Committee(committeeEnum, year));

if (committee.getId() == 0) {
committeeRepository.save(committee);
}

product.setCommittee(committee);
}

/**
* @param productEventsSync of type ProductEventsSync
*/
@Override
public void deleteProduct(ProductEventsSync productEventsSync) {
Product product = this.getProductByKey(productEventsSync.getKey());

productRepository.delete(product.getId());
}

/**
* Get a Product by its key.
*
* @param key of type Key
* @return Product
*/
private Product getProductByKey(String key) {
return productRepository.findOneByKey(key).orElseThrow(ProductNotFoundException::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ch.wisv.payments.rest.eventsync;

import ch.wisv.payments.admin.products.ProductService;
import ch.wisv.payments.exception.ProductNotFoundException;
import ch.wisv.payments.model.eventsync.ProductEventsSync;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.nio.charset.Charset;
import java.util.Base64;

import static ch.wisv.payments.model.eventsync.EventsSyncEnum.valueOf;
import static ch.wisv.payments.util.ResponseEntityBuilder.createResponseEntity;

@RestController
@CrossOrigin
@RequestMapping(value = "/api/chevents/sync")
@Validated
public class EventsSyncRestController {

@Value("${events.username}")
@NotNull
private String username;

@Value("${events.password}")
@NotNull
private String password;

/**
* ProductService.
*/
private final ProductService productService;

private final EventsSyncProductService eventsSyncProductService;

/**
* Constructor ProductService.
*
* @param productService of type ProductService
* @param eventsSyncProductService of type EventsSyncProductService
*/
public EventsSyncRestController(ProductService productService, EventsSyncProductService eventsSyncProductService) {
this.productService = productService;
this.eventsSyncProductService = eventsSyncProductService;
}

@PostMapping("/product/")
public ResponseEntity<?> eventSync(HttpServletRequest request, @RequestBody ProductEventsSync productEventsSync) {
String[] credentials = this.decryptBasicAuthHeader(request.getHeader("Authorization"));

if (!this.authChEvents(credentials)) {
return createResponseEntity(HttpStatus.UNAUTHORIZED, "User is not authorized", null);
}

try {
switch (valueOf(productEventsSync.getTrigger())) {
case PRODUCT_CREATE_EDIT:
this.createOrUpdate(productEventsSync);
break;
case PRODUCT_DELETE:
eventsSyncProductService.deleteProduct(productEventsSync);
break;
}
} catch (IllegalArgumentException e) {
return createResponseEntity(HttpStatus.BAD_REQUEST, "Events trigger not supported!", null);
}

return createResponseEntity(HttpStatus.OK, null, null);
}

/**
* Check if user is CH Events.
*
* @param credentials of type String[]
*/
private boolean authChEvents(String[] credentials) {
return credentials[0].equals(this.username) && credentials[1].equals(this.password);
}

/**
* Determine if a Product should be updated or created.
*
* @param productEventsSync of type ProductEventsSync
*/
private void createOrUpdate(ProductEventsSync productEventsSync) {
try {
productService.getProductByKey(productEventsSync.getKey());

eventsSyncProductService.editProduct(productEventsSync);
} catch (ProductNotFoundException e) {
eventsSyncProductService.createProduct(productEventsSync);
}
}

/**
* Decrypt the Basic Auth header.
*
* @param basicAuth of type String
* @return String[] with username and password
*/
private String[] decryptBasicAuthHeader(String basicAuth) {
String base64Credentials = basicAuth.substring("Basic".length()).trim();
String credentials = new String(Base64.getDecoder().decode(base64Credentials),
Charset.forName("UTF-8"));

return credentials.split(":", 2);
}
}
Loading