Skip to content

Commit

Permalink
[backend] Asset, Endpoint & AssetGroup (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
RomuDeuxfois committed Jan 10, 2024
1 parent 18edee1 commit 42b492f
Show file tree
Hide file tree
Showing 21 changed files with 733 additions and 2 deletions.
1 change: 0 additions & 1 deletion openex-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<bcpg-jdk15on.version>1.70</bcpg-jdk15on.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-email.version>1.5</commons-email.version>
<commons-validator.version>1.7</commons-validator.version>
<flyway.version>9.0.3</flyway.version>
<opensaml.version>4.1.1</opensaml.version>
<springdoc.version>1.7.0</springdoc.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.openex.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.Statement;

@Component
public class V2_64__Assets_Asset_Groups extends BaseJavaMigration {

@Override
public void migrate(Context context) throws Exception {
Connection connection = context.getConnection();
Statement select = connection.createStatement();
// Create table asset
select.execute("""
CREATE TABLE IF NOT EXISTS assets (
asset_id varchar(255) not null constraint assets_pkey primary key,
asset_external_id varchar(255),
asset_name varchar(255) not null,
asset_description text,
asset_created_at timestamp not null default now(),
asset_updated_at timestamp not null default now()
);
CREATE INDEX IF NOT EXISTS idx_assets on assets (asset_id);
""");
// Create table endpoint
select.execute("""
CREATE TABLE IF NOT EXISTS endpoints (
endpoint_id varchar(255) not null constraint endpoints_pkey primary key,
endpoint_ip varchar(255) not null,
endpoint_hostname varchar(255),
endpoint_os varchar(255)
) INHERITS (assets);
""");
// Create table asset groups
select.execute("""
CREATE TABLE IF NOT EXISTS asset_groups (
asset_group_id varchar(255) not null constraint asset_groups_pkey primary key,
asset_group_name varchar(255) not null,
asset_group_description text,
asset_group_created_at timestamp not null default now(),
asset_group_updated_at timestamp not null default now()
);
CREATE INDEX IF NOT EXISTS idx_asset_groups on asset_groups (asset_group_id);
""");
// Add association table between asset and asset groups
select.execute("""
CREATE TABLE IF NOT EXISTS asset_groups_assets (
asset_group_id varchar(255) not null constraint asset_group_id_fk references asset_groups on delete cascade,
asset_id varchar(255) not null constraint asset_id_fk references endpoints on delete cascade,
constraint asset_groups_assets_pkey primary key (asset_group_id, asset_id)
);
CREATE INDEX IF NOT EXISTS idx_asset_groups_assets_asset on asset_groups_assets (asset_group_id);
CREATE INDEX IF NOT EXISTS idx_asset_groups_assets_asset on asset_groups_assets (asset_id);
""");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.openex.rest.asset.endpoint;

import io.openex.database.model.Endpoint;
import io.openex.rest.asset.endpoint.form.EndpointInput;
import io.openex.service.asset.EndpointService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.security.RolesAllowed;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;

import static io.openex.database.model.User.ROLE_ADMIN;

@RequiredArgsConstructor
@RestController
public class EndpointApi {

public static final String ENDPOINT_URI = "/api/endpoints";

private final EndpointService endpointService;

@PostMapping(ENDPOINT_URI)
@RolesAllowed(ROLE_ADMIN)
public Endpoint createEndpoint(@Valid @RequestBody final EndpointInput input) {
Endpoint endpoint = new Endpoint();
endpoint.setUpdateAttributes(input);
return this.endpointService.createEndpoint(endpoint);
}

@GetMapping(ENDPOINT_URI)
@PreAuthorize("isObserver()")
public List<Endpoint> endpoints() {
return this.endpointService.endpoints();
}

@PutMapping(ENDPOINT_URI + "/{endpointId}")
@RolesAllowed(ROLE_ADMIN)
public Endpoint updateEndpoint(
@PathVariable @NotBlank final String endpointId,
@Valid @RequestBody final EndpointInput input) {
Endpoint endpoint = this.endpointService.endpoint(endpointId);
endpoint.setUpdateAttributes(input);
return this.endpointService.updateEndpoint(endpoint);
}

@DeleteMapping(ENDPOINT_URI + "/{endpointId}")
@RolesAllowed(ROLE_ADMIN)
public void deleteEndpoint(@PathVariable @NotBlank final String endpointId) {
this.endpointService.deleteEndpoint(endpointId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.openex.rest.asset.endpoint.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.openex.rest.asset.form.AssetInput;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.validation.constraints.NotBlank;

import static io.openex.config.AppConfig.MANDATORY_MESSAGE;

@EqualsAndHashCode(callSuper = true)
@Data
public class EndpointInput extends AssetInput {


@NotBlank(message = MANDATORY_MESSAGE)
@JsonProperty("endpoint_ip")
private String ip;

@JsonProperty("endpoint_hostname")
private String hostname;

@NotBlank(message = MANDATORY_MESSAGE)
@JsonProperty("endpoint_os")
private String os;

}
23 changes: 23 additions & 0 deletions openex-api/src/main/java/io/openex/rest/asset/form/AssetInput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.openex.rest.asset.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import javax.validation.constraints.NotBlank;

import static io.openex.config.AppConfig.MANDATORY_MESSAGE;

@Data
public abstract class AssetInput {

@JsonProperty("asset_external_id")
private String externalId;

@NotBlank(message = MANDATORY_MESSAGE)
@JsonProperty("asset_name")
private String name;

@JsonProperty("asset_description")
private String description;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.openex.rest.asset_group;

import io.openex.database.model.AssetGroup;
import io.openex.rest.asset_group.form.AssetGroupInput;
import io.openex.service.AssetGroupService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.security.RolesAllowed;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;

import static io.openex.database.model.User.ROLE_ADMIN;

@RestController
@RequiredArgsConstructor
public class AssetGroupApi {

public static final String ASSET_GROUP_URI = "/api/asset_groups";

private final AssetGroupService assetGroupService;

@PostMapping(ASSET_GROUP_URI)
@RolesAllowed(ROLE_ADMIN)
public AssetGroup createAssetGroup(@Valid @RequestBody final AssetGroupInput input) {
AssetGroup assetGroup = new AssetGroup();
assetGroup.setUpdateAttributes(input);
return this.assetGroupService.createAssetGroup(assetGroup);
}

@GetMapping(ASSET_GROUP_URI)
@PreAuthorize("isObserver()")
public List<AssetGroup> assetGroups() {
return this.assetGroupService.assetGroups();
}

@PutMapping(ASSET_GROUP_URI + "/{assetGroupId}")
@RolesAllowed(ROLE_ADMIN)
public AssetGroup updateAssetGroup(
@PathVariable @NotBlank final String assetGroupId,
@Valid @RequestBody final AssetGroupInput input) {
AssetGroup assetGroup = this.assetGroupService.assetGroup(assetGroupId);
assetGroup.setUpdateAttributes(input);
return this.assetGroupService.updateAssetGroup(assetGroup);
}

@DeleteMapping(ASSET_GROUP_URI + "/{assetGroupId}")
@RolesAllowed(ROLE_ADMIN)
public void deleteAssetGroup(@PathVariable @NotBlank final String assetGroupId) {
this.assetGroupService.deleteAssetGroup(assetGroupId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.openex.rest.asset_group.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.NotBlank;

import static io.openex.config.AppConfig.MANDATORY_MESSAGE;

@Getter
@Setter
public class AssetGroupInput {

@NotBlank(message = MANDATORY_MESSAGE)
@JsonProperty("asset_group_name")
private String name;

@JsonProperty("asset_group_description")
private String description;
}
42 changes: 42 additions & 0 deletions openex-api/src/main/java/io/openex/service/AssetGroupService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.openex.service;

import io.openex.database.model.AssetGroup;
import io.openex.database.repository.AssetGroupRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

import static io.openex.helper.StreamHelper.fromIterable;
import static java.time.Instant.now;

@RequiredArgsConstructor
@Service
public class AssetGroupService {

private final AssetGroupRepository assetGroupRepository;

public AssetGroup createAssetGroup(@NotNull final AssetGroup assetGroup) {
return this.assetGroupRepository.save(assetGroup);
}

public AssetGroup assetGroup(@NotBlank final String assetGroupId) {
return this.assetGroupRepository.findById(assetGroupId).orElseThrow();
}

public List<AssetGroup> assetGroups() {
return fromIterable(this.assetGroupRepository.findAll());
}

public AssetGroup updateAssetGroup(@NotNull final AssetGroup assetGroup) {
assetGroup.setUpdatedAt(now());
return this.assetGroupRepository.save(assetGroup);
}

public void deleteAssetGroup(@NotBlank final String assetGroupId) {
this.assetGroupRepository.deleteById(assetGroupId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.openex.service.asset;

import io.openex.database.model.Endpoint;
import io.openex.database.repository.EndpointRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

import static io.openex.helper.StreamHelper.fromIterable;
import static java.time.Instant.now;

@RequiredArgsConstructor
@Service
public class EndpointService {

private final EndpointRepository endpointRepository;

public Endpoint createEndpoint(@NotNull final Endpoint endpoint) {
return this.endpointRepository.save(endpoint);
}

public Endpoint endpoint(@NotBlank final String endpointId) {
return this.endpointRepository.findById(endpointId).orElseThrow();
}

public List<Endpoint> endpoints() {
return fromIterable(this.endpointRepository.findAll());
}

public Endpoint updateEndpoint(@NotNull final Endpoint endpoint) {
endpoint.setUpdatedAt(now());
return this.endpointRepository.save(endpoint);
}

public void deleteEndpoint(@NotBlank final String endpointId) {
this.endpointRepository.deleteById(endpointId);
}

}
Loading

0 comments on commit 42b492f

Please sign in to comment.