Skip to content

Commit

Permalink
Move REST API Doc build in docs/
Browse files Browse the repository at this point in the history
Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
  • Loading branch information
avgustinmm committed Nov 29, 2023
1 parent ad87672 commit 67b5bc1
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 127 deletions.
4 changes: 2 additions & 2 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ content/rest-api/*.yaml
node_modules
package.json
package-lock.json
# themse
themes
# themes
themes/hugo-material-docs
# hugo
public
.hugo_build.lock
Empty file removed docs/content/rest-api/_index.md
Empty file.
67 changes: 28 additions & 39 deletions docs/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
Copyright (c) 2018 Bosch Software Innovations GmbH and others
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
Expand All @@ -16,8 +16,9 @@
<artifactId>hawkbit-parent</artifactId>
<version>${revision}</version>
</parent>

<artifactId>docs</artifactId>
<packaging>pom</packaging>
<!-- <packaging>pom</packaging>-->
<name>hawkBit :: Documentation</name>
<description>Documentation for hawkBit</description>

Expand Down Expand Up @@ -56,43 +57,6 @@

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-openapi</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-update-server</artifactId>
<version>${project.version}</version>
<classifier>mgmt-openapi</classifier>
<type>yaml</type>
<overWrite>true</overWrite>
<outputDirectory>${basedir}/content/rest-api</outputDirectory>
<destFileName>mgmt.yaml</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-update-server</artifactId>
<version>${project.version}</version>
<classifier>ddi-openapi</classifier>
<type>yaml</type>
<overWrite>true</overWrite>
<outputDirectory>${basedir}/content/rest-api</outputDirectory>
<destFileName>ddi.yaml</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
Expand Down Expand Up @@ -162,4 +126,29 @@
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Test -->
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
38 changes: 38 additions & 0 deletions docs/src/main/java/org/eclipse/hawkbit/doc/Start.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
41 changes: 41 additions & 0 deletions docs/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -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/**
14 changes: 14 additions & 0 deletions docs/src/main/resources/banner.txt
Original file line number Diff line number Diff line change
@@ -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.

33 changes: 33 additions & 0 deletions docs/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* SPDX-License-Identifier: EPL-2.0
*/

package org.eclipse.hawkbit.app;
package org.eclipse.hawkbit.doc;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
Expand Down Expand Up @@ -36,49 +36,49 @@
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith({SharedSqlTestDatabaseExtension.class})
class RestApiDocTest {
private static final String MANAGEMENT_PREFIX = "mgmt-openapi";
private static final String DDI_PREFIX = "ddi-openapi";
private static final String TARGET_DIRECTORY = "target/rest-api/";
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;

private final ObjectMapper objectMapper = new ObjectMapper();

@Test
void openapiJson() throws IOException {
ResponseEntity<String> response =
final ResponseEntity<String> response =
restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
String openapiDoc = response.getBody();
final String openapiDoc = response.getBody();
assertThat(openapiDoc).isNotNull();
splitDocumentation(openapiDoc);
}

private void splitDocumentation(String json) throws IOException {
private static void splitDocumentation(final String json) throws IOException {
processDocumentation(json, true);
processDocumentation(json, false);
}

private void processDocumentation(String json, boolean isMgmt) throws IOException {
JsonNode rootNode = objectMapper.readTree(json);
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 void updateJsonNodeForApi(JsonNode rootNode, boolean isMgmt) {
private static void updateJsonNodeForApi(final JsonNode rootNode, final boolean isMgmt) {
removeTags(rootNode, isMgmt);
removePaths(rootNode, isMgmt);
removeComponents(rootNode, isMgmt);
}

private void removeTags(JsonNode rootNode, boolean isMgmt) {
ArrayNode tagsNode = (ArrayNode) rootNode.get("tags");
ArrayNode modifiedTagsNode = objectMapper.createArrayNode();
private static void removeTags(final JsonNode rootNode, final boolean isMgmt) {
final ArrayNode tagsNode = (ArrayNode) rootNode.get("tags");
final ArrayNode modifiedTagsNode = OBJECT_MAPPER.createArrayNode();

for (JsonNode tagNode : tagsNode) {
for (final JsonNode tagNode : tagsNode) {
String tagName = tagNode.get("name").asText();
if (isMgmt != tagName.startsWith("DDI")) {
modifiedTagsNode.add(tagNode);
Expand All @@ -87,17 +87,17 @@ private void removeTags(JsonNode rootNode, boolean isMgmt) {

((ObjectNode) rootNode).set("tags", modifiedTagsNode);
}
private void removePaths(JsonNode rootNode, boolean isMgmt) {
ObjectNode pathsNode = (ObjectNode) rootNode.get("paths");
List<String> fieldsToRemove = new ArrayList<>();
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 -> {
JsonNode pathNode = pathsNode.get(fieldName);
final JsonNode pathNode = pathsNode.get(fieldName);
pathNode.fieldNames().forEachRemaining(path -> {
JsonNode methodNode = pathNode.get(path);
JsonNode tagsNode = methodNode.get("tags");
final JsonNode methodNode = pathNode.get(path);
final JsonNode tagsNode = methodNode.get("tags");
if (tagsNode != null) {
for (JsonNode tagNode : tagsNode) {
String tag = tagNode.asText();
final String tag = tagNode.asText();
if (isMgmt == tag.startsWith("DDI")) {
fieldsToRemove.add(fieldName);
break;
Expand All @@ -109,8 +109,8 @@ private void removePaths(JsonNode rootNode, boolean isMgmt) {
fieldsToRemove.forEach(pathsNode::remove);
}

private void removeComponents(JsonNode rootNode, boolean isMgmt) {
ObjectNode schemasNode = (ObjectNode) rootNode.get("components").get("schemas");
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 -> {
Expand All @@ -121,33 +121,33 @@ private void removeComponents(JsonNode rootNode, boolean isMgmt) {
fieldsToRemove.forEach(schemasNode::remove);
}

private boolean shouldDeleteComponent(String fieldName, boolean isMgmt) {
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("ExceptionInfo"));

}

private void saveDocumentation(JsonNode rootNode, boolean isMgmt) throws IOException {
String prefix = isMgmt ? MANAGEMENT_PREFIX : DDI_PREFIX;
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 void saveAsJson(JsonNode rootNode, String prefix) throws IOException {
Path targetPath = getTargetPath(prefix, ".json");
Files.writeString(targetPath, objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode));
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 void saveAsYaml(JsonNode rootNode, String prefix) throws IOException {
YAMLMapper yamlMapper = new YAMLMapper();
Path targetPath = getTargetPath(prefix, ".yaml");
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 Path getTargetPath(String prefix, String extension) throws IOException {
Path targetPath = Paths.get(TARGET_DIRECTORY + prefix + extension);
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;
}
Expand Down
Loading

0 comments on commit 67b5bc1

Please sign in to comment.