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

fix(openapi): Uses openrewrite to convert swagger to openapi annotations #1813

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
14 changes: 13 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ plugins {
id "org.jetbrains.kotlin.jvm" version "$kotlinVersion" apply false
id "org.jetbrains.kotlin.plugin.allopen" version "$kotlinVersion" apply false
id "org.jetbrains.dokka" version "0.10.1" apply false
id("org.openrewrite.rewrite") version("6.16.4")

}
rewrite {
activeRecipe("org.openrewrite.openapi.swagger.SwaggerToOpenAPI")
}

dependencies {
rewrite("org.openrewrite.recipe:rewrite-openapi:0.5.3")
}

allprojects {
apply plugin: 'io.spinnaker.project'
apply plugin: 'org.openrewrite.rewrite'

group = "io.spinnaker.gate"

if ([korkVersion, fiatVersion].find { it.endsWith('-SNAPSHOT') }) {
repositories {
mavenLocal()
Expand All @@ -21,11 +30,14 @@ allprojects {
apply plugin: 'groovy'

repositories {
mavenCentral()

maven { url 'https://build.shibboleth.net/nexus/content/repositories/releases/' }
maven { url 'https://repository.mulesoft.org/releases/' }
}

dependencies {

implementation enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
annotationProcessor platform("io.spinnaker.kork:kork-bom:$korkVersion")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
Expand Down
1 change: 1 addition & 0 deletions gate-bom/gate-bom.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
api("io.spinnaker.fiat:fiat-api:$fiatVersion")
api("io.spinnaker.fiat:fiat-core:$fiatVersion")


rootProject
.subprojects
.findAll { it != project }
Expand Down
2 changes: 2 additions & 0 deletions gate-integrations-gremlin/gate-integrations-gremlin.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
dependencies {
implementation project(":gate-core")
implementation "io.swagger.core.v3:swagger-annotations"

implementation "io.spinnaker.kork:kork-swagger"
implementation "io.spinnaker.kork:kork-web"
implementation "com.netflix.spectator:spectator-api"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.netflix.spinnaker.gate.controllers.gremlin;

import com.netflix.spinnaker.gate.services.gremlin.GremlinService;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -24,14 +24,14 @@ public GremlinController(GremlinService gremlinService) {
this.gremlinService = gremlinService;
}

@ApiOperation(value = "Retrieve a list of gremlin command templates")
@Operation(summary = "Retrieve a list of gremlin command templates")
@RequestMapping(value = "/templates/command", method = RequestMethod.POST)
List listCommandTemplates(@RequestBody(required = true) Map apiKeyMap) {
String apiKeyValue = (String) apiKeyMap.get(APIKEY_KEY);
return gremlinService.getCommandTemplates("Key " + apiKeyValue);
}

@ApiOperation(value = "Retrieve a list of gremlin target templates")
@Operation(summary = "Retrieve a list of gremlin target templates")
@RequestMapping(value = "/templates/target", method = RequestMethod.POST)
List listTargetTemplates(@RequestBody(required = true) Map apiKeyMap) {
String apiKeyValue = (String) apiKeyMap.get(APIKEY_KEY);
Expand Down
3 changes: 2 additions & 1 deletion gate-plugins/gate-plugins.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ apply from: "${project.rootDir}/gradle/kotlin.gradle"
apply from: "${project.rootDir}/gradle/kotlin-test.gradle"

dependencies {
implementation platform(project(":gate-bom"))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This very probably could go away post kork change.

implementation project(":gate-api")
implementation project(":gate-core")

Expand All @@ -27,7 +28,7 @@ dependencies {
implementation "io.spinnaker.kork:kork-plugins"
implementation "io.spinnaker.kork:kork-web"

implementation "io.swagger:swagger-annotations"
implementation "io.swagger.core.v3:swagger-annotations"

implementation "org.springframework:spring-web"
implementation "org.pf4j:pf4j-update"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
package com.netflix.spinnaker.gate.plugins.deck

import com.netflix.spinnaker.kork.web.exceptions.NotFoundException
import io.swagger.annotations.ApiOperation
import io.swagger.v3.oas.annotations.Operation

import java.util.concurrent.TimeUnit
import javax.servlet.http.HttpServletResponse
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
Expand All @@ -36,13 +37,13 @@ class DeckPluginsController(
private val deckPluginService: DeckPluginService
) {

@ApiOperation(value = "Retrieve a plugin manifest")
@Operation(summary = "Retrieve a plugin manifest")
@GetMapping("/plugin-manifest.json")
fun getPluginManifest(): List<DeckPluginVersion> {
return deckPluginService.getPluginsManifests()
}

@ApiOperation(value = "Retrieve a single plugin asset by version")
@Operation(summary = "Retrieve a single plugin asset by version")
@GetMapping("/{pluginId}/{pluginVersion}/{asset:.*}")
fun getPluginAsset(
@PathVariable pluginId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import com.netflix.spinnaker.gate.plugins.web.PluginService
import com.netflix.spinnaker.gate.plugins.web.SpinnakerExtensionsConfigProperties
import com.netflix.spinnaker.gate.services.internal.Front50Service
import com.netflix.spinnaker.kork.plugins.update.internal.SpinnakerPluginInfo
import io.swagger.annotations.ApiOperation
import io.swagger.v3.oas.annotations.Operation
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.security.access.prepost.PreAuthorize
Expand All @@ -42,7 +42,7 @@ class PluginInfoController(
private val spinnakerExtensionsConfigProperties: SpinnakerExtensionsConfigProperties
) {

@ApiOperation(value = "Persist plugin metadata information")
@Operation(summary = "Persist plugin metadata information")
@RequestMapping(
method = [RequestMethod.POST, RequestMethod.PUT],
consumes = [MediaType.APPLICATION_JSON_VALUE]
Expand All @@ -52,7 +52,7 @@ class PluginInfoController(
return pluginService.upsertPluginInfo(pluginInfo)
}

@ApiOperation(value = "Delete plugin info with the provided Id")
@Operation(summary = "Delete plugin info with the provided Id")
@PreAuthorize("hasPermission(#this.this.appName, 'APPLICATION', 'WRITE')")
@RequestMapping(
value = ["/{id:.+}"],
Expand All @@ -64,7 +64,7 @@ class PluginInfoController(
return pluginService.deletePluginInfo(id)
}

@ApiOperation(value = "Get all plugin info objects")
@Operation(summary = "Get all plugin info objects")
@RequestMapping(method = [RequestMethod.GET])
fun getAllPluginInfo(@RequestParam(value = "service", required = false) service: String?): List<*> {
return front50Service.getPluginInfo(service)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import com.netflix.spinnaker.gate.services.internal.SwabbieService
import com.netflix.spinnaker.kork.plugins.SpinnakerPluginDescriptor
import com.netflix.spinnaker.kork.plugins.SpinnakerPluginManager
import com.netflix.spinnaker.kork.plugins.update.SpinnakerUpdateManager
import io.swagger.annotations.ApiOperation
import io.swagger.v3.oas.annotations.Operation

import java.util.stream.Collectors
import org.pf4j.PluginWrapper
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -43,7 +44,7 @@ class PluginsInstalledController(

private val log by lazy { LoggerFactory.getLogger(javaClass) }

@ApiOperation(value = "Get all installed Spinnaker plugins")
@Operation(summary = "Get all installed Spinnaker plugins")
@RequestMapping(method = [RequestMethod.GET])
fun getInstalledPlugins(@RequestParam(value = "service", required = false) service: String?): Map<String, List<SpinnakerPluginDescriptor>> {
return when (service) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import com.netflix.spinnaker.gate.plugins.web.PluginService
import com.netflix.spinnaker.kork.exceptions.SystemException
import com.netflix.spinnaker.kork.plugins.update.internal.SpinnakerPluginInfo
import com.netflix.spinnaker.security.AuthenticatedRequest
import io.swagger.annotations.ApiOperation
import io.swagger.v3.oas.annotations.Operation

import java.lang.String.format
import lombok.SneakyThrows
import okhttp3.MediaType
Expand Down Expand Up @@ -55,7 +56,7 @@ class PluginPublishController(
private val okHttpClient: OkHttpClient = okHttpClientProvider.getClient(DefaultServiceEndpoint("front50", front50Url))

@SneakyThrows
@ApiOperation(value = "Publish a plugin binary and the plugin info metadata.")
@Operation(summary = "Publish a plugin binary and the plugin info metadata.")
@PostMapping("/{pluginId}/{pluginVersion}", consumes = [MULTIPART_FORM_DATA_VALUE])
fun publishPlugin(
@RequestPart("plugin") body: MultipartFile,
Expand Down
2 changes: 1 addition & 1 deletion gate-web/gate-web.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ dependencies {
force = true // Unpin it after adoption of spring-boot-starter-graphql
}

implementation "io.springfox:springfox-swagger2"
implementation "org.springdoc:springdoc-openapi-ui:1.8.0"

implementation "io.cloudevents:cloudevents-spring:2.5.0"
implementation "io.cloudevents:cloudevents-json-jackson:2.5.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
public class CloudEventHandlerConfiguration implements WebMvcConfigurer {

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(cloudEventHttpMessageConverter());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.netflix.spinnaker.gate.config

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.config.DefaultServiceEndpoint
import com.netflix.spinnaker.config.OkHttp3ClientConfiguration
Expand All @@ -28,8 +27,6 @@ import com.netflix.spinnaker.fiat.shared.FiatPermissionEvaluator
import com.netflix.spinnaker.fiat.shared.FiatService
import com.netflix.spinnaker.fiat.shared.FiatStatus
import com.netflix.spinnaker.filters.AuthenticatedRequestFilter
import com.netflix.spinnaker.gate.converters.JsonHttpMessageConverter
import com.netflix.spinnaker.gate.converters.YamlHttpMessageConverter
import com.netflix.spinnaker.gate.filters.RequestLoggingFilter
import com.netflix.spinnaker.gate.filters.RequestSheddingFilter
import com.netflix.spinnaker.gate.filters.ResetAuthenticatedRequestFilter
Expand Down Expand Up @@ -57,7 +54,6 @@ import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.Primary
import org.springframework.core.Ordered
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.util.CollectionUtils
import org.springframework.web.client.RestTemplate
Expand Down Expand Up @@ -101,19 +97,6 @@ class GateConfig {
@Autowired
Jackson2ObjectMapperBuilder objectMapperBuilder

/**
* This needs to be before the yaml converter in order for json to be the default
* response type.
*/
@Bean
AbstractJackson2HttpMessageConverter jsonHttpMessageConverter() {
return new JsonHttpMessageConverter(objectMapperBuilder.build())
}

@Bean
AbstractJackson2HttpMessageConverter yamlHttpMessageConverter() {
return new YamlHttpMessageConverter(objectMapperBuilder.factory(new YAMLFactory()).build())
}

@Bean
RequestContextProvider requestContextProvider() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,32 @@

package com.netflix.spinnaker.gate.config


import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.gate.converters.JsonHttpMessageConverter
import com.netflix.spinnaker.gate.converters.YamlHttpMessageConverter
import com.netflix.spinnaker.gate.filters.ContentCachingFilter
import com.netflix.spinnaker.gate.interceptors.RequestContextInterceptor
import com.netflix.spinnaker.gate.interceptors.ResponseHeaderInterceptor
import com.netflix.spinnaker.gate.interceptors.ResponseHeaderInterceptorConfigurationProperties
import com.netflix.spinnaker.gate.retrofit.UpstreamBadRequest
import com.netflix.spinnaker.kork.dynamicconfig.DynamicConfigService
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import com.netflix.spinnaker.kork.web.interceptors.MetricsInterceptor
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpStatus
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import org.springframework.web.servlet.handler.HandlerMappingIntrospector
Expand All @@ -54,6 +59,9 @@ public class GateWebConfig implements WebMvcConfigurer {

@Autowired
DynamicConfigService dynamicConfigService
@Autowired
Jackson2ObjectMapperBuilder objectMapperBuilder


@Autowired
Registry spectatorRegistry
Expand All @@ -68,7 +76,7 @@ public class GateWebConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(
new MetricsInterceptor(
this.registry, "controller.invocations", ["account", "region"], ["BasicErrorController"]
this.registry, "controller.invocations", ["account", "region"], null, ["BasicErrorController"]
)
)

Expand All @@ -81,8 +89,12 @@ public class GateWebConfig implements WebMvcConfigurer {
return new HandlerMappingIntrospector(context)
}


// Add the ability to disable as this breaks numerous integration patterns
@Override
void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new JsonHttpMessageConverter(objectMapperBuilder.build()))
converters.add( new YamlHttpMessageConverter(objectMapperBuilder.factory(new YAMLFactory()).build()))
}
// Add the ability to disable as this breaks numerous integration patterns
@Bean
@ConditionalOnProperty(value = "content.cachingFilter.enabled", matchIfMissing = true)
Filter contentCachingFilter() {
Expand Down Expand Up @@ -126,9 +138,4 @@ public class GateWebConfig implements WebMvcConfigurer {
]
}
}

@Override
void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false)
}
}
Loading
Loading