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

Add error & latency injector with headers #17

Merged
merged 6 commits into from
Sep 20, 2023
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
2 changes: 1 addition & 1 deletion checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<!-- <module name="AvoidStarImport" />-->
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports">
Expand Down
Binary file modified cp-trace/cp-trace-agent.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,27 @@ public class ChaosConfiguration {

private static final short RANDOM_EXCEPTION_RATIO = 5;


@Value("${chaos.enabled:false}")
private boolean enabled;

private boolean isRandomException;

private final Random random = new Random();

public void setEnabled(boolean enabled) {
isRandomException = enabled;
}

public void restore() {
isRandomException = enabled;
}

public ChaosConfiguration() {
restore();
}


private static class ServerDownException extends Exception {
ServerDownException() {
super("Server is down!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,18 @@
import com.catchpoint.tracing.demo.todo.model.User;
import com.catchpoint.tracing.demo.todo.service.TodoService;
import com.catchpoint.tracing.demo.todo.model.Todo;
import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
Expand All @@ -36,6 +28,7 @@
@RequestMapping("/todos")
public class TodoController {

private static final int TEN_SECONDS_AS_MILLIS = 10 * 1000;
private static final List<String> USER_EMAIL_LIST = Arrays.asList(
"[email protected]",
"[email protected]",
Expand All @@ -61,13 +54,33 @@ public TodoController(TodoService service, ChaosConfiguration chaosConfiguration
this.chaosConfiguration = chaosConfiguration;
this.userClient = userCheckEnabled ? userClient : null;
}

public void handleMap(Map<String, String> map) {
if (map.containsKey("x-chaos-inject-error") && map.get("x-chaos-inject-error").equals("true")) {
throw new RuntimeException("This error is thrown for testing purpose.");
} else if (map.containsKey("x-chaos-inject-latency") && map.get("x-chaos-inject-latency").equals("true")) {
chaosConfiguration.setEnabled(false);
try {
Thread.sleep(TEN_SECONDS_AS_MILLIS);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
chaosConfiguration.restore();
}
}

public void checkUserAccess(Map<String, String> headers) {
handleMap(headers);

String userEmail = USER_EMAIL_LIST.get(RANDOM.nextInt(USER_EMAIL_LIST.size()));
if (headers.containsKey("x-chaos-inject-auth-error") &&
headers.get("x-chaos-inject-auth-error").equals("true")) {
userEmail = USER_EMAIL_LIST.get(USER_EMAIL_LIST.size() - 1);
}

private void checkUserAccess() {
if (userClient != null) {
String userEmail = USER_EMAIL_LIST.get(RANDOM.nextInt(USER_EMAIL_LIST.size()));
InvocationAPI.setTag("email", userEmail);
Span span = tracer.buildSpan("getUserByEmail").withTag("email", userEmail).start();
Scope scope = tracer.activateSpan(span);
try {
User user = userClient.get("/users/get/" + userEmail, User.class);
if (user == null) {
Expand All @@ -79,23 +92,22 @@ private void checkUserAccess() {
} else {
throw new ResponseStatusException(HttpStatus.resolve(e.getResponseCode()));
}
} finally {
scope.close();
}
}
}

@GetMapping("/list")
public ResponseEntity<List<Todo>> findTodos() {
checkUserAccess();
public ResponseEntity<List<Todo>> findTodos(@RequestHeader Map<String, String> headers) {
checkUserAccess(headers);

List<Todo> todos = service.findTodos();
return ResponseEntity.ok(todos);
}

@PostMapping("/add")
public ResponseEntity<Todo> addTodo(@Valid @RequestBody Todo request) throws Exception {
checkUserAccess();
public ResponseEntity<Todo> addTodo(@Valid @RequestBody Todo request,
@RequestHeader Map<String, String> headers) throws Exception {
checkUserAccess(headers);

chaosConfiguration.throwRandomException();

Expand All @@ -104,32 +116,33 @@ public ResponseEntity<Todo> addTodo(@Valid @RequestBody Todo request) throws Exc
}

@PutMapping("/update/{id}")
public ResponseEntity<Todo> updateTodo(@PathVariable Long id, @Valid @RequestBody Todo request) {
checkUserAccess();
public ResponseEntity<Todo> updateTodo(@PathVariable Long id, @Valid @RequestBody Todo request,
@RequestHeader Map<String, String> headers) {
checkUserAccess(headers);

Todo todo = service.updateTodo(id, request);
return ResponseEntity.ok(todo);
}

@DeleteMapping("/delete/{id}")
public ResponseEntity<Void> deleteTodo(@PathVariable Long id) {
checkUserAccess();
public ResponseEntity<Void> deleteTodo(@PathVariable Long id, @RequestHeader Map<String, String> headers) {
checkUserAccess(headers);

service.deleteTodo(id);
return ResponseEntity.noContent().build();
}

@PostMapping("/duplicate/{id}")
public ResponseEntity<Todo> duplicateTodo(@PathVariable Long id) {
checkUserAccess();
public ResponseEntity<Todo> duplicateTodo(@PathVariable Long id, @RequestHeader Map<String, String> headers) {
checkUserAccess(headers);

Todo todo = service.duplicateTodo(id);
return ResponseEntity.ok(todo);
}

@PostMapping("/clear-completed")
public ResponseEntity<Void> clearCompletedTodo() {
checkUserAccess();
public ResponseEntity<Void> clearCompletedTodo(@RequestHeader Map<String, String> headers) {
checkUserAccess(headers);

service.clearCompletedTodo();
return ResponseEntity.ok().build();
Expand Down
Loading