Rename docs to site (#1550)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-01-18 15:31:20 +02:00
committed by GitHub
parent d15bcce8d2
commit f2a4f6f591
106 changed files with 5 additions and 25 deletions

View File

@@ -0,0 +1,38 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.doc;
import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* A {@link SpringBootApplication} annotated class with a main method to start.
* The minimal configuration for the stand alone hawkBit server.
*
*/
@SpringBootApplication
@EnableHawkbitManagedSecurityConfiguration
// Exception squid:S1118 - Spring boot standard behavior
@SuppressWarnings({ "squid:S1118" })
public class Start {
/**
* Main method to start the spring-boot application.
*
* @param args
* the VM arguments.
*/
// Exception squid:S2095 - Spring boot standard behavior
@SuppressWarnings({ "squid:S2095" })
public static void main(final String[] args) {
SpringApplication.run(Start.class, args);
}
}

View File

@@ -0,0 +1,41 @@
#
# Copyright (c) 2023 Bosch.IO GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# User Security
spring.security.user.name=admin
spring.security.user.password={noop}admin
spring.main.allow-bean-definition-overriding=true
# Http Encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
# DDI authentication configuration
hawkbit.server.ddi.security.authentication.anonymous.enabled=false
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
# Optional events
hawkbit.server.repository.publish-target-poll-event=false
## Configuration for DMF/RabbitMQ integration
hawkbit.dmf.rabbitmq.enabled=false
# Swagger Configuration
#springdoc.swagger-ui.path=/update-server-documentation
#springdoc.api-docs.path=/update-server-api-docs
springdoc.show-oauth2-endpoints=true
springdoc.api-docs.version=openapi_3_0
springdoc.show-login-endpoint=true
springdoc.packages-to-scan=org.eclipse.hawkbit.mgmt,org.eclipse.hawkbit.ddi
springdoc.swagger-ui.oauth2RedirectUrl=/login/oauth2/code/suite
springdoc.paths-to-exclude=/system/**

View File

@@ -0,0 +1,14 @@
______ _ _ _ _ ____ _ _
| ____| | (_) | | | | | _ \(_) |
| |__ ___| |_ _ __ ___ ___ | |__ __ ___ _| | _| |_) |_| |_
| __| / __| | | '_ \/ __|/ _ \ | '_ \ / _` \ \ /\ / / |/ / _ <| | __|
| |___| (__| | | |_) \__ \ __/ | | | | (_| |\ V V /| <| |_) | | |_
|______\___|_|_| .__/|___/\___| |_| |_|\__,_| \_/\_/ |_|\_\____/|_|\__|
| |
|_|
Eclipse hawkBit Update Server ${application.formatted-version}
using Spring Boot ${spring-boot.formatted-version}
Go to https://www.eclipse.org/hawkbit for more information.

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.eclipse.hawkbit.eventbus.DeadEventListener" level="WARN" />
<Logger name="org.springframework.boot.actuate.audit.listener.AuditListener" level="WARN" />
<Logger name="org.hibernate.validator.internal.util.Version" level="WARN" />
<!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" />
<!-- Suppressing "More than one Servlet Mapping defined. WebSocket may not work"
error due to the way VaadinServletConfiguration configures the endpoints mapping ("/UI" and "/UI/*").
At the end only the first "/UI" is taken for websocket communication. -->
<logger name="org.atmosphere.util.IOUtils" level="OFF" />
<Root level="INFO">
<appender-ref ref="CONSOLE" />
</Root>
</configuration>

View File

@@ -0,0 +1,155 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.doc;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.eclipse.hawkbit.repository.test.util.SharedSqlTestDatabaseExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith({SharedSqlTestDatabaseExtension.class})
class RestApiDocTest {
private static final String MANAGEMENT_PREFIX = "mgmt";
private static final String DDI_PREFIX = "ddi";
private static final String TARGET_DIRECTORY = "content/rest-api/";
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void openapiJson() throws IOException {
final ResponseEntity<String> response =
restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
final String openapiDoc = response.getBody();
assertThat(openapiDoc).isNotNull();
splitDocumentation(openapiDoc);
}
private static void splitDocumentation(final String json) throws IOException {
processDocumentation(json, true);
processDocumentation(json, false);
}
private static void processDocumentation(final String json, final boolean isMgmt) throws IOException {
final JsonNode rootNode = OBJECT_MAPPER.readTree(json);
updateJsonNodeForApi(rootNode, isMgmt);
saveDocumentation(rootNode, isMgmt);
}
private static void updateJsonNodeForApi(final JsonNode rootNode, final boolean isMgmt) {
removeTags(rootNode, isMgmt);
removePaths(rootNode, isMgmt);
removeComponents(rootNode, isMgmt);
}
private static void removeTags(final JsonNode rootNode, final boolean isMgmt) {
final ArrayNode tagsNode = (ArrayNode) rootNode.get("tags");
final ArrayNode modifiedTagsNode = OBJECT_MAPPER.createArrayNode();
for (final JsonNode tagNode : tagsNode) {
String tagName = tagNode.get("name").asText();
if (isMgmt != tagName.startsWith("DDI")) {
modifiedTagsNode.add(tagNode);
}
}
((ObjectNode) rootNode).set("tags", modifiedTagsNode);
}
private static void removePaths(final JsonNode rootNode, final boolean isMgmt) {
final ObjectNode pathsNode = (ObjectNode) rootNode.get("paths");
final List<String> fieldsToRemove = new ArrayList<>();
pathsNode.fieldNames().forEachRemaining(fieldName -> {
final JsonNode pathNode = pathsNode.get(fieldName);
pathNode.fieldNames().forEachRemaining(path -> {
final JsonNode methodNode = pathNode.get(path);
final JsonNode tagsNode = methodNode.get("tags");
if (tagsNode != null) {
for (JsonNode tagNode : tagsNode) {
final String tag = tagNode.asText();
if (isMgmt == tag.startsWith("DDI")) {
fieldsToRemove.add(fieldName);
break;
}
}
}
});
});
fieldsToRemove.forEach(pathsNode::remove);
}
private static void removeComponents(final JsonNode rootNode, final boolean isMgmt) {
final ObjectNode schemasNode = (ObjectNode) rootNode.get("components").get("schemas");
List<String> fieldsToRemove = new ArrayList<>();
schemasNode.fieldNames().forEachRemaining(fieldName -> {
if (shouldDeleteComponent(fieldName, isMgmt)) {
fieldsToRemove.add(fieldName);
}
});
fieldsToRemove.forEach(schemasNode::remove);
}
private static boolean shouldDeleteComponent(final String fieldName, final boolean isMgmt) {
if (isMgmt) {
return fieldName.startsWith("Ddi");
}
return !(fieldName.startsWith("Ddi") || fieldName.equals("Link") || fieldName.equals("Links") || fieldName.equals("ExceptionInfo"));
}
private static void saveDocumentation(final JsonNode rootNode, final boolean isMgmt) throws IOException {
final String prefix = isMgmt ? MANAGEMENT_PREFIX : DDI_PREFIX;
saveAsJson(rootNode, prefix);
saveAsYaml(rootNode, prefix);
}
private static void saveAsJson(final JsonNode rootNode, final String prefix) throws IOException {
final Path targetPath = getTargetPath(prefix, ".json");
Files.writeString(targetPath, OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode));
}
private static void saveAsYaml(final JsonNode rootNode, final String prefix) throws IOException {
final YAMLMapper yamlMapper = new YAMLMapper();
final Path targetPath = getTargetPath(prefix, ".yaml");
Files.writeString(targetPath, yamlMapper.writeValueAsString(rootNode));
}
private static Path getTargetPath(final String prefix, final String extension) throws IOException {
final Path targetPath = Paths.get(TARGET_DIRECTORY + prefix + extension);
Files.createDirectories(targetPath.getParent());
return targetPath;
}
}