Skip to content

Commit

Permalink
Merge pull request #133 from lat-lon/fix/serverUrlInOpenAPI-9925-198
Browse files Browse the repository at this point in the history
Fix serverUrl in OpenAPI document
  • Loading branch information
copierrj authored Nov 20, 2024
2 parents 9678a98 + 42aecfb commit 8e00633
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.slf4j.Logger;

import javax.inject.Inject;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -117,17 +118,19 @@ public class OafOpenApiFilter extends AbstractSpecFilter {

public static final String GEOMETRY_PROPERTY_NAME = "geometry";

private final UriInfo uriInfo;

private final String datasetId;

private final OafDatasetConfiguration datasetConfiguration;

@Inject
private DeegreeWorkspaceInitializer deegreeWorkspaceInitializer;

public OafOpenApiFilter( String datasetId, DeegreeWorkspaceInitializer deegreeWorkspaceInitializer )
throws UnknownDatasetId {
public OafOpenApiFilter(UriInfo uriInfo, String datasetId,
DeegreeWorkspaceInitializer deegreeWorkspaceInitializer) throws UnknownDatasetId {
this.uriInfo = uriInfo;
this.datasetId = datasetId;

OafDatasets oafDatasets = deegreeWorkspaceInitializer.getOafDatasets();
this.datasetConfiguration = oafDatasets.getDataset( datasetId );
}
Expand All @@ -140,18 +143,15 @@ public Optional<OpenAPI> filterOpenAPI( OpenAPI openAPI, Map<String, List<String
return super.filterOpenAPI( openAPI, params, cookies, headers );
}

private void filterServers( OpenAPI openAPI ) {
if ( openAPI.getServers() == null || openAPI.getServers().isEmpty() )
openAPI.addServersItem( new Server() );
Server server = openAPI.getServers().get( 0 );
StringBuilder url = new StringBuilder();
if ( server.getUrl() != null )
url.append( server.getUrl() );
if ( server.getUrl() == null || !server.getUrl().endsWith( "/" ) )
url.append( "/" );
url.append( "datasets/" ).append( datasetId );
server.setUrl( url.toString() );
}
private void filterServers(OpenAPI openAPI) {
if (openAPI.getServers() == null || openAPI.getServers().isEmpty())
openAPI.addServersItem(new Server());
Server server = openAPI.getServers().get(0);
String absolutePathToOpenApi = uriInfo.getBaseUriBuilder().path("datasets").path(datasetId).toString();
server.setUrl(absolutePathToOpenApi);
}



private void filterPaths( OpenAPI openAPI ) {
Paths paths = openAPI.getPaths();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class OpenApiCreator {
@Inject
private DeegreeWorkspaceInitializer deegreeWorkspaceInitializer;

public OpenAPI createOpenApi( HttpHeaders headers, String datasetId )
public OpenAPI createOpenApi(HttpHeaders headers, UriInfo uriInfo, String datasetId )
throws Exception {
OpenAPI oas = createOpenApiDocument( datasetId );
SwaggerConfiguration oasConfig = createSwaggerConfiguration( oas );
Expand All @@ -92,9 +92,9 @@ public OpenAPI createOpenApi( HttpHeaders headers, String datasetId )
if ( oas2 != null && ctx.getOpenApiConfiguration() != null
&& ctx.getOpenApiConfiguration().getFilterClass() != null ) {
try {
OafOpenApiFilter filter = new OafOpenApiFilter( datasetId, deegreeWorkspaceInitializer );
OafOpenApiFilter filter = new OafOpenApiFilter( uriInfo, datasetId, deegreeWorkspaceInitializer );
SpecFilter f = new SpecFilter();
oas2 = f.filter( oas2, filter, getQueryParams( uriInfo.getQueryParameters() ), getCookies( headers ),
oas2 = f.filter( oas2, filter, getQueryParams( this.uriInfo.getQueryParameters() ), getCookies( headers ),
getHeaders( headers ) );
} catch ( Exception e ) {
LOG.error( "failed to load filter", e );
Expand Down Expand Up @@ -147,20 +147,10 @@ private OpenAPI createOpenApiDocument( String datasetId )
DatasetMetadata metadata = oafConfiguration.getServiceMetadata();
Info info = createInfo( metadata );
OpenAPI oas = new OpenAPI();
addserver( oas );
oas.info( info );
return oas;
}

private void addserver( OpenAPI oas ) {
String contextPath = servletConfig.getServletContext().getContextPath();
if ( contextPath != null && !contextPath.isEmpty() ) {
Server server = new Server().url( contextPath );
List<Server> servers = Collections.singletonList( server );
oas.servers( servers );
}
}

private Info createInfo( DatasetMetadata metadata ) {
String title = metadata.getTitle();
String description = metadata.getDescription();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@
*/
@Path("/datasets/{datasetId}/api")
public class OpenApi {

/**
* Name for parameter that allows enabling allowing all origins for CORS.
* Name for parameter that allows enabling allowing all origins for CORS.
*/
public static final String PARAMETER_CORS_ALLOWALL = "deegree.oaf.openapi.cors.allow_all";

private final boolean corsAllowAll = TunableParameter.get(PARAMETER_CORS_ALLOWALL, false);

private static final Logger LOG = getLogger( OpenApi.class );
Expand All @@ -84,36 +84,36 @@ public Response getOpenApiOpenApiJson(
@PathParam("datasetId")
String datasetId )
throws Exception {
return respondWithOpenApi( headers, datasetId, true );
return respondWithOpenApi( headers, uriInfo, datasetId, true );
}

@GET
@Produces({ APPLICATION_OPENAPI_YAML, APPLICATION_YAML })
@Operation(operationId = "openApi", summary = "api documentation", description = "api documentation")
@Tag(name = "Capabilities")
public Response getOpenApiOpenApiYaml(
@Context HttpHeaders headers,
@Context UriInfo uriInfo,
@PathParam("datasetId")
@Context HttpHeaders headers,
@Context UriInfo uriInfo,
@PathParam("datasetId")
String datasetId )
throws Exception {
return respondWithOpenApi( headers, datasetId, false );
return respondWithOpenApi( headers, uriInfo, datasetId, false );
}

private Response respondWithOpenApi(HttpHeaders headers, String datasetId, boolean json) throws Exception {
OpenAPI openApi = this.openApiCreator.createOpenApi( headers, datasetId );
private Response respondWithOpenApi(HttpHeaders headers, UriInfo uriInfo, String datasetId, boolean json) throws Exception {
OpenAPI openApi = this.openApiCreator.createOpenApi( headers, uriInfo, datasetId );

if ( openApi == null )
return Response.status( 404 ).build();

String rendered;
if (json) {
rendered = Json.mapper().writeValueAsString( openApi );
}
else {
rendered = Yaml.mapper().writeValueAsString( openApi );
}

ResponseBuilder resp = Response.status( Response.Status.OK )
.entity( rendered );
if (corsAllowAll) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,6 @@
*/
package org.deegree.services.oaf.filter;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.OpenAPIV3Parser;
import org.deegree.services.oaf.openapi.OafOpenApiFilter;
import org.deegree.services.oaf.workspace.DeegreeWorkspaceInitializer;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Test;

import javax.xml.namespace.QName;
import java.net.URL;
import java.util.Map;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import static javax.ws.rs.core.MediaType.TEXT_HTML;
Expand All @@ -52,12 +34,49 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.xml.namespace.QName;
import java.net.URI;
import java.net.URL;
import java.util.List;
import java.util.Map;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.parser.OpenAPIV3Parser;
import org.deegree.services.oaf.openapi.OafOpenApiFilter;
import org.deegree.services.oaf.workspace.DeegreeWorkspaceInitializer;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mock;

/**
* @author <a href="mailto:goltz@lat-lon.de">Lyn Goltz </a>
*/
public class OafOpenApiFilterTest {

private static final String BASE_URI = "http://localhost:8081/deegree-services-oaf";

@Mock
static UriInfo uriInfo = mock(UriInfo.class);

@BeforeClass
public static void mockUriInfo(){
when(uriInfo.getBaseUriBuilder()).thenReturn(UriBuilder.fromUri(BASE_URI),UriBuilder.fromUri(BASE_URI),UriBuilder.fromUri(BASE_URI));
}

@Test
public void testFilterOperation()
throws Exception {
Expand All @@ -67,7 +86,7 @@ public void testFilterOperation()

DeegreeWorkspaceInitializer deegreeWorkspaceInitializer = mockWorkspaceInitializer();

OafOpenApiFilter filter = new OafOpenApiFilter( "oaf", deegreeWorkspaceInitializer );
OafOpenApiFilter filter = new OafOpenApiFilter( uriInfo, "oaf", deegreeWorkspaceInitializer );
filter.filterOpenAPI( openAPI, null, null, null );

Paths paths = openAPI.getPaths();
Expand All @@ -94,6 +113,10 @@ public void testFilterOperation()
assertThat( paths.get( "/collections/strassenbaumkataster/items/{featureId}" ),
hasResponseMediaType( APPLICATION_GEOJSON, APPLICATION_GML, APPLICATION_GML_32, APPLICATION_GML_SF0,
APPLICATION_GML_SF2, TEXT_HTML ) );

List<Server> servers = openAPI.getServers();
assertThat(servers.size(), is(1));
assertThat(servers.get(0).getUrl(), is("http://localhost:8081/deegree-services-oaf/datasets/oaf"));
}

@Test
Expand All @@ -106,7 +129,7 @@ public void testFilterOperation_WithPrimitiveList()
DeegreeWorkspaceInitializer deegreeWorkspaceInitializer = mockWorkspaceInitializer(
new QName( "http://www.deegree.org/app", "KitaEinrichtungen" ) );

OafOpenApiFilter filter = new OafOpenApiFilter( "oaf", deegreeWorkspaceInitializer );
OafOpenApiFilter filter = new OafOpenApiFilter( uriInfo, "oaf", deegreeWorkspaceInitializer );
filter.filterOpenAPI( openAPI, null, null, null );

Paths paths = openAPI.getPaths();
Expand All @@ -133,6 +156,10 @@ public void testFilterOperation_WithPrimitiveList()
ArraySchema leistungsnameSchema = (ArraySchema) propertiesSchema.getProperties().get( "Leistungsname" );
assertThat( leistungsnameSchema.getType(), is( "array" ) );
assertThat( leistungsnameSchema.getItems().getType(), is( "string" ) );

List<Server> servers = openAPI.getServers();
assertThat(servers.size(), is(1));
assertThat(servers.get(0).getUrl(), is("http://localhost:8081/deegree-services-oaf/datasets/oaf"));
}

@Test
Expand All @@ -145,7 +172,7 @@ public void testFilterOperation_WithComplexData()
DeegreeWorkspaceInitializer deegreeWorkspaceInitializer = mockWorkspaceInitializer(
new QName( "http://www.deegree.org/datasource/feature/sql", "Zuwanderung" ) );

OafOpenApiFilter filter = new OafOpenApiFilter( "oaf", deegreeWorkspaceInitializer );
OafOpenApiFilter filter = new OafOpenApiFilter( uriInfo, "oaf", deegreeWorkspaceInitializer );
filter.filterOpenAPI( openAPI, null, null, null );

Paths paths = openAPI.getPaths();
Expand All @@ -172,6 +199,10 @@ public void testFilterOperation_WithComplexData()
Schema countryComplexItems = countryComplexSchema.getItems();
assertThat( ( (Schema) countryComplexItems.getProperties().get( "name" ) ).getType(), is( "string" ) );
assertThat( ( (Schema) countryComplexItems.getProperties().get( "pop" ) ).getType(), is( "number" ) );

List<Server> servers = openAPI.getServers();
assertThat(servers.size(), is(1));
assertThat(servers.get(0).getUrl(), is("http://localhost:8081/deegree-services-oaf/datasets/oaf"));
}

private Matcher<PathItem> hasResponseMediaType( String... mediaTypes ) {
Expand Down

0 comments on commit 8e00633

Please sign in to comment.