Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add AMQP support #215

Merged
merged 1 commit into from
Mar 21, 2025
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
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ Use the spring boot's dev profile to use default values that are just for non-pr

#### From Command Line

1.Start with oauth
1. Start with oauth profile

```shell
./mvmw clean install -DskipTests
$ java -jar target/terra-boot-*.jar\
--spring.profiles.active=oauth \
--spring.profiles.active=oauth,dev \
--authorization.token.type=${token-type} \
--authorization.server.endpoint=${server-endpoint} \
--authorization.api.client.id=${client-id} \
Expand All @@ -123,7 +123,7 @@ $ java -jar target/terra-boot-*.jar\

```shell
./mvmw clean install -DskipTests
$ java -jar target/terra-boot-*.jar
$ java -jar --spring.profiles.active=dev target/terra-boot-*.jar
```

#### From IDE
Expand All @@ -147,6 +147,39 @@ http://localhost:9090
http://localhost:9090/swagger-ui/index.html
```

### AMQP support
#### Start AMQP Broker

Use RabbitMQ as the default provider for AMQP. Start the broker and create queues using the following command:

```shell
mkdir -p ~/docker/rabbitmq/data
docker run -d \
--user 1000:1000 \
--name xpanse-rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
-v ~/docker/rabbitmq/data:/var/lib/rabbitmq \
-e RABBITMQ_DEFAULT_USER=xpanse \
-e RABBITMQ_DEFAULT_PASS=Xpanse@2023 \
rabbitmq:4.0.7-management
```
Access the RabbitMQ management console at http://localhost:15672 with username `xpanse` and password `Xpanse@2023` after the container is started.

#### Enable AMQP
Start the application with the `amqp` profile.

```shell
./mvmw clean install -DskipTests
$ java -jar --spring.profiles.active=dev,amqp target/terra-boot-*.jar
```

#### AsyncApi Docs and UI

When the application started with the `amqp` profile, the AsyncApi docs and UI Console are enabled.
The AsyncApi docs can be accessed at http://localhost:9090/queues/docs.
The AsyncApi UI can be accessed at http://localhost:9090/queues/asyncapi-ui.html.

### Production

#### Docker Image
Expand Down
27 changes: 27 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<maven.surefire.plugin.version>3.5.2</maven.surefire.plugin.version>
<maven.enforcer.plugin.version>3.5.0</maven.enforcer.plugin.version>
<spotless.version>2.44.2</spotless.version>
<springwolf.version>1.11.0</springwolf.version>
</properties>
<dependencyManagement>
<dependencies>
Expand Down Expand Up @@ -63,6 +64,32 @@
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- Spring AMQP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- Springwolf AsyncAPI-->
<dependency>
<groupId>io.github.springwolf</groupId>
<artifactId>springwolf-asyncapi</artifactId>
<version>${springwolf.version}</version>
</dependency>
<dependency>
<groupId>io.github.springwolf</groupId>
<artifactId>springwolf-core</artifactId>
<version>${springwolf.version}</version>
</dependency>
<dependency>
<groupId>io.github.springwolf</groupId>
<artifactId>springwolf-amqp</artifactId>
<version>${springwolf.version}</version>
</dependency>
<dependency>
<groupId>io.github.springwolf</groupId>
<artifactId>springwolf-ui</artifactId>
<version>${springwolf.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* SPDX-License-Identifier: Apache-2.0
* SPDX-FileCopyrightText: Huawei Inc.
*/

package org.eclipse.xpanse.terra.boot.api.config;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.eclipse.xpanse.terra.boot.models.request.TerraformRequest;
import org.eclipse.xpanse.terra.boot.models.request.TerraformRequestDeserializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

/** Configuration class for Jackson. */
@Configuration
public class JacksonConfig {

/**
* Create a ObjectMapper with the given module.
*
* @return objectMapper bean.
*/
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
SimpleModule terraformRequestModule = new SimpleModule();
terraformRequestModule.addDeserializer(
TerraformRequest.class, new TerraformRequestDeserializer());
mapper.registerModule(terraformRequestModule);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}

/**
* Define MappingJackson2HttpMessageConverter with the given objectMapper.
*
* @param objectMapper objectMapper
* @return mappingJackson2HttpMessageConverter bean
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(
ObjectMapper objectMapper) {
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,32 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.xpanse.terra.boot.models.TerraBootSystemStatus;
import org.eclipse.xpanse.terra.boot.terraform.service.TerraformDirectoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.eclipse.xpanse.terra.boot.models.response.TerraBootSystemStatus;
import org.eclipse.xpanse.terra.boot.terraform.service.TerraformRequestService;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/** REST controller for admin services of terra-boot. */
@Slf4j
@CrossOrigin
@Profile("!amqp")
@RestController
@RequestMapping("/terra-boot")
public class TerraBootAdminApi {

private final TerraformDirectoryService terraformDirectoryService;

@Autowired
public TerraBootAdminApi(
@Qualifier("terraformDirectoryService")
TerraformDirectoryService terraformDirectoryService) {
this.terraformDirectoryService = terraformDirectoryService;
}
@Resource private TerraformRequestService requestService;

/**
* Method to find out the current state of the system.
Expand All @@ -46,6 +44,12 @@ public TerraBootAdminApi(
@GetMapping(value = "/health", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public TerraBootSystemStatus healthCheck() {
return terraformDirectoryService.tfHealthCheck();
TerraBootSystemStatus healthStatus = requestService.healthCheck(UUID.randomUUID());
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
healthStatus.setServiceType(request.getScheme());
healthStatus.setServiceUrl(request.getRequestURL().toString());
return healthStatus;
}
}
Loading