Skip to content

Commit

Permalink
Feat: VHVAPM-530/531
Browse files Browse the repository at this point in the history
  • Loading branch information
levinkerschberger committed Aug 27, 2024
1 parent 1d88be3 commit 533c4c4
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ fabric.properties
/ui/build_packageClient/

**/.DS_Store

**/node_modules
**/.nuxt
10 changes: 10 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,18 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-validation'
annotationProcessor 'org.projectlombok:lombok'

// Actuator - for management endpoints
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// Swagger - for API documentation
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'

// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// Management

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.configuration.controller;

import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import rocks.inspectit.gepard.agentmanager.configuration.model.InspectitConfiguration;
import rocks.inspectit.gepard.agentmanager.configuration.service.ConfigurationService;

@RestController
@RequestMapping("/api/v1/agent-configuration")
@RequiredArgsConstructor
public class ConfigurationController {

private final ConfigurationService configurationService;

@GetMapping
@Operation(summary = "Get the agent configuration.")
public ResponseEntity<InspectitConfiguration> getAgentConfiguration() {
InspectitConfiguration configuration = configurationService.getConfiguration();

// No config available
if (Objects.isNull(configuration)) {
return ResponseEntity.noContent().build();
}

return ResponseEntity.ok().body(configurationService.getConfiguration());
}

@PutMapping
@Operation(summary = "Update the agent configuration.")
public ResponseEntity<InspectitConfiguration> updateAgentConfiguration(
@Valid @RequestBody InspectitConfiguration configuration) {
configurationService.updateConfiguration(configuration);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.configuration.model;

import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import rocks.inspectit.gepard.agentmanager.configuration.model.instrumentation.InstrumentationConfiguration;

/** Model of an inspectit gepard configuration. */
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class InspectitConfiguration {

@Valid private InstrumentationConfiguration instrumentation = new InstrumentationConfiguration();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.configuration.model.instrumentation;

import jakarta.validation.Valid;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* The Instrumentation Configuration contains all configuration related to instrumentation. e.g
* scopes, rules, actions.
*/
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class InstrumentationConfiguration {

@Valid private List<Scope> scopes = List.of();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.configuration.model.instrumentation;

import jakarta.validation.constraints.NotNull;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* Represents a scope in the instrumentation configuration. A scope defines a set of methods which
* should be instrumented.
*/
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Scope {

@NotNull(message = "Fqn is missing.") private String fqn;

private List<String> methods = List.of();

private boolean enabled = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.configuration.service;

import org.springframework.stereotype.Service;
import rocks.inspectit.gepard.agentmanager.configuration.model.InspectitConfiguration;

@Service
public class ConfigurationService {

private InspectitConfiguration inspectitConfiguration;

public InspectitConfiguration getConfiguration() {
return inspectitConfiguration;
}

public void updateConfiguration(InspectitConfiguration configuration) {
inspectitConfiguration = configuration;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.connection.controller;

import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
Expand All @@ -25,6 +26,7 @@ public class ConnectionController {
private final ConnectionService connectionService;

@PostMapping
@Operation(summary = "Connect an agent to the agent manager.")
public ResponseEntity<Void> connect(@Valid @RequestBody CreateConnectionRequest connectRequest) {
Connection connection = connectionService.handleConnectRequest(connectRequest);
return ResponseEntity.created(
Expand All @@ -36,11 +38,13 @@ public ResponseEntity<Void> connect(@Valid @RequestBody CreateConnectionRequest
}

@GetMapping
@Operation(summary = "Get all connections.")
public ResponseEntity<List<ConnectionDto>> getConnections() {
return ResponseEntity.ok(connectionService.getConnections());
}

@GetMapping("/{id}")
@Operation(summary = "Get a connection by id.")
public ResponseEntity<ConnectionDto> getConnection(@PathVariable UUID id) {
return ResponseEntity.ok(connectionService.getConnection(id));
}
Expand Down
12 changes: 12 additions & 0 deletions backend/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ server:
bundle: "server"
enabled-protocols: "TLSv1.3"

management:
server:
port: 9090
endpoints:
web:
exposure:
include: "openapi, swagger-ui"

springdoc:
show-actuator: true
use-management-port: true

inspectit:
gepard:
security:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* (C) 2024 */
package rocks.inspectit.gepard.agentmanager.configuration.controller;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import rocks.inspectit.gepard.agentmanager.configuration.model.InspectitConfiguration;
import rocks.inspectit.gepard.agentmanager.configuration.model.instrumentation.InstrumentationConfiguration;
import rocks.inspectit.gepard.agentmanager.configuration.model.instrumentation.Scope;
import rocks.inspectit.gepard.agentmanager.configuration.service.ConfigurationService;

@WebMvcTest(controllers = ConfigurationController.class)
class ConfigurationControllerTest {

@Autowired private MockMvc mockMvc;

@Autowired private ObjectMapper objectMapper;

@MockBean private ConfigurationService configurationService;

@Test
void getConfiguration_whenNoConfigAvailable_shouldReturnNoContent() throws Exception {

when(configurationService.getConfiguration()).thenReturn(null);

mockMvc.perform(get("/api/v1/agent-configuration")).andExpect(status().isNoContent());
}

@Test
void getConfiguration_whenConfigAvailable_shouldReturnOk() throws Exception {
when(configurationService.getConfiguration()).thenReturn(new InspectitConfiguration());

mockMvc
.perform(get("/api/v1/agent-configuration"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().json(objectMapper.writeValueAsString(new InspectitConfiguration())));
}

@Test
void updateConfiguration_shouldReturnOkAndConfiguration() throws Exception {

InspectitConfiguration configuration = createConfiguration();

when(configurationService.getConfiguration()).thenReturn(configuration);

mockMvc
.perform(
get("/api/v1/agent-configuration")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(configuration)))
.andExpect(status().isOk());
}

private InspectitConfiguration createConfiguration() {
Scope scope = new Scope("org.test.package", List.of("testMethod"), true);
InstrumentationConfiguration instrumentationConfiguration =
new InstrumentationConfiguration(List.of(scope));
return new InspectitConfiguration(instrumentationConfiguration);
}
}

0 comments on commit 533c4c4

Please sign in to comment.