Skip to content

Commit

Permalink
Merge pull request #5342 from jGauravGupta/FISH-1312
Browse files Browse the repository at this point in the history
FISH-1312 MP OpenAPI hidden attribute is ignored
  • Loading branch information
jGauravGupta authored Jul 21, 2021
2 parents 5aa29d2 + 950bd96 commit 95e95b5
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) [2018-2020] Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) [2018-2021] Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -110,7 +110,10 @@ public static Header createInstance(AnnotationModel annotation, ApiContext conte
from.setExplode(annotation.getValue("explode", Boolean.class));
AnnotationModel schemaAnnotation = annotation.getValue("schema", AnnotationModel.class);
if (schemaAnnotation != null) {
from.setSchema(SchemaImpl.createInstance(schemaAnnotation, context));
Boolean hidden = schemaAnnotation.getValue("hidden", Boolean.class);
if (hidden == null || !hidden) {
from.setSchema(SchemaImpl.createInstance(schemaAnnotation, context));
}
}
extractAnnotations(annotation, context, "examples", "name", ExampleImpl::createInstance, from::addExample);
from.setExample(annotation.getValue("example", Object.class));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) [2018-2020] Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) [2018-2021] Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -80,7 +80,10 @@ public static ContentImpl createInstance(AnnotationModel annotation, ApiContext
mediaType.setExample(annotation.getValue("example", String.class));
AnnotationModel schemaAnnotation = annotation.getValue("schema", AnnotationModel.class);
if (schemaAnnotation != null) {
mediaType.setSchema(SchemaImpl.createInstance(schemaAnnotation, context));
Boolean hidden = schemaAnnotation.getValue("hidden", Boolean.class);
if (hidden == null || !hidden) {
mediaType.setSchema(SchemaImpl.createInstance(schemaAnnotation, context));
}
}
extractAnnotations(annotation, context, "encoding", "name", EncodingImpl::createInstance, mediaType::addEncoding);
return from;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) [2018-2020] Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) [2018-2021] Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -103,7 +103,10 @@ public static Parameter createInstance(AnnotationModel annotation, ApiContext co
from.setAllowReserved(annotation.getValue("allowReserved", Boolean.class));
AnnotationModel schemaAnnotation = annotation.getValue("schema", AnnotationModel.class);
if (schemaAnnotation != null) {
from.setSchema(SchemaImpl.createInstance(schemaAnnotation, context));
Boolean hidden = schemaAnnotation.getValue("hidden", Boolean.class);
if (hidden == null || !hidden) {
from.setSchema(SchemaImpl.createInstance(schemaAnnotation, context));
}
}
extractAnnotations(annotation, context, "examples", "name", ExampleImpl::createInstance, from::addExample);
from.setExample(annotation.getValue("example", Object.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ public void visitCookieParam(AnnotationModel param, AnnotatedElement element, Ap
}

private static void addParameter(AnnotatedElement element, ApiContext context, String name, In in, Boolean required) {
Boolean hidden = false;
AnnotationModel paramAnnotation = element.getAnnotation(org.eclipse.microprofile.openapi.annotations.parameters.Parameter.class.getName());
if (paramAnnotation != null) {
hidden = paramAnnotation.getValue("hidden", Boolean.class);
}
if (hidden != null && hidden) {
return;
}

Parameter newParameter = new ParameterImpl();
newParameter.setName(name);
newParameter.setIn(in);
Expand Down Expand Up @@ -567,7 +576,16 @@ private Schema visitSchemaClass(

for (FieldModel field : clazz.getFields()) {
final String fieldName = field.getName();
if (!field.isTransient() && !fieldName.startsWith("this$")) {
Boolean hidden = false;
AnnotationModel fieldSchemaAnnotation = field
.getAnnotation(org.eclipse.microprofile.openapi.annotations.media.Schema.class.getName());
if (fieldSchemaAnnotation != null) {
hidden = fieldSchemaAnnotation.getValue("hidden", Boolean.class);
}

if (!Boolean.TRUE.equals(hidden)
&& !field.isTransient()
&& !fieldName.startsWith("this$")) {
final Schema existingProperty = schema.getProperties().get(fieldName);
final Schema newProperty = createSchema(null, context, field, clazz, parameterizedInterfaces);
if (existingProperty != null) {
Expand Down Expand Up @@ -632,38 +650,40 @@ private void visitSchemaField(AnnotationModel schemaAnnotation, FieldModel field
private void visitSchemaFieldOrMethod(AnnotationModel schemaAnnotation, AnnotatedElement fieldOrMethod,
ExtensibleType<?> declaringType, String typeName, ApiContext context) {
assert (fieldOrMethod instanceof FieldModel) || (fieldOrMethod instanceof MethodModel);
Boolean hidden = schemaAnnotation.getValue("hidden", Boolean.class);
if (hidden == null || !hidden) {
// Get the schema object name
String schemaName = ModelUtils.getSchemaName(context, fieldOrMethod);
SchemaImpl schema = SchemaImpl.createInstance(schemaAnnotation, context);

// Get the parent schema object name
String parentName = null;
AnnotationModel classSchemaAnnotation = context.getAnnotationInfo(declaringType)
.getAnnotation(org.eclipse.microprofile.openapi.annotations.media.Schema.class);
if (classSchemaAnnotation != null) {
parentName = classSchemaAnnotation.getValue("name", String.class);
}
if (parentName == null || parentName.isEmpty()) {
parentName = declaringType.getSimpleName();
}

// Get the schema object name
String schemaName = ModelUtils.getSchemaName(context, fieldOrMethod);
SchemaImpl schema = SchemaImpl.createInstance(schemaAnnotation, context);

// Get the parent schema object name
String parentName = null;
AnnotationModel classSchemaAnnotation = context.getAnnotationInfo(declaringType)
.getAnnotation(org.eclipse.microprofile.openapi.annotations.media.Schema.class);
if (classSchemaAnnotation != null) {
parentName = classSchemaAnnotation.getValue("name", String.class);
}
if (parentName == null || parentName.isEmpty()) {
parentName = declaringType.getSimpleName();
}
// Get or create the parent schema object
final Components components = context.getApi().getComponents();
Schema parentSchema = components.getSchemas().getOrDefault(parentName, new SchemaImpl());
components.addSchema(parentName, parentSchema);

// Get or create the parent schema object
final Components components = context.getApi().getComponents();
Schema parentSchema = components.getSchemas().getOrDefault(parentName, new SchemaImpl());
components.addSchema(parentName, parentSchema);
Schema property = parentSchema.getProperties().getOrDefault(schemaName, new SchemaImpl());
parentSchema.addProperty(schemaName, property);
if (schema.isRequired()) {
parentSchema.addRequired(schemaName);
}

Schema property = parentSchema.getProperties().getOrDefault(schemaName, new SchemaImpl());
parentSchema.addProperty(schemaName, property);
if (schema.isRequired()) {
parentSchema.addRequired(schemaName);
}
if (property.getRef() == null) {
property.setType(ModelUtils.getSchemaType(typeName, context));
}

if (property.getRef() == null) {
property.setType(ModelUtils.getSchemaType(typeName, context));
SchemaImpl.merge(schema, property, true, context);
}

SchemaImpl.merge(schema, property, true, context);
}

private static void visitSchemaParameter(AnnotationModel schemaAnnotation, org.glassfish.hk2.classmodel.reflect.Parameter parameter, ApiContext context) {
Expand Down Expand Up @@ -938,6 +958,10 @@ public void visitParameters(AnnotationModel annotation, AnnotatedElement element
@Override
public void visitParameter(AnnotationModel annotation, AnnotatedElement element, ApiContext context) {
Parameter matchedParam = null;
Boolean hidden = annotation.getValue("hidden", Boolean.class);
if (hidden != null && hidden) {
return;
}
Parameter parameter = ParameterImpl.createInstance(annotation, context);

if (element instanceof org.glassfish.hk2.classmodel.reflect.Parameter) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) [2019-2021] Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -39,7 +39,9 @@
*/
package fish.payara.microprofile.openapi.test.app.application;

import com.fasterxml.jackson.databind.JsonNode;
import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest;
import fish.payara.microprofile.openapi.test.util.JsonUtils;
import static fish.payara.microprofile.openapi.test.util.JsonUtils.path;
import javax.json.Json;
import javax.json.JsonObject;
Expand All @@ -51,17 +53,75 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;

/**
* Test to verify that using {@code hidden} does not cause errors as suggested by PAYARA-3259.
* Test to verify that using {@code hidden} does not cause errors as suggested
* by PAYARA-3259.
*/
@Path("/example")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class HiddenTest extends OpenApiApplicationTest {

@Schema
public class User {

private Long id;

private String email;

@Schema(hidden = true)
private String passwordHash;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPasswordHash() {
return passwordHash;
}

public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
}

class Teacher extends User {

private int secretPin;

public int getSecretPin() {
return secretPin;
}

public void setSecretPin(int secretPin) {
this.secretPin = secretPin;
}



}

@GET
@Path("/{name}")
@Operation(hidden = true)
Expand All @@ -72,8 +132,65 @@ public Response hello(@PathParam("name") String name) {
return Response.ok(message).build();
}

@GET
@Path("/{userId}")
@Produces(MediaType.APPLICATION_JSON)
@APIResponse(
responseCode = "400",
description = "NotFound",
content = @Content(
schema = @Schema(implementation = User.class)
)
)
@APIResponse(
responseCode = "900",
description = "Invalid",
content = @Content(
schema = @Schema(implementation = User.class, hidden = true)
)
)
public User sayHello(
@Parameter(
name = "userId",
description = "ID of user",
required = true
)
@PathParam("userId") Long userId,
@Parameter(
name = "password",
description = "Password of user",
required = true,
hidden = true
)
@PathParam("password") String password) {
return new User();
}

@Test
public void hiddenPropertyDoesNotCauseErrors() {
public void hiddenOperationDoesNotCauseErrors() {
assertNotNull(path(getOpenAPIJson(), "paths./test/example/{name}"));
}

@Test
public void hiddenSchemaPropertyDoesNotCauseErrors() {
System.out.println(getOpenAPIJson());
JsonNode properties = JsonUtils.path(getOpenAPIJson(), "components.schemas.User.properties");
assertEquals("number", properties.get("id").get("type").textValue());
assertEquals("string", properties.get("email").get("type").textValue());
assertNull(properties.get("passwordHash"));
}

@Test
public void hiddenSchemaDoesNotCauseErrors() {
JsonNode responses = JsonUtils.path(getOpenAPIJson(), "paths./test/example/{userId}.get.responses");
assertNotNull(responses.get("400").get("content").get("application/json").get("schema"));
assertNull(responses.get("900").get("content").get("application/json").get("schema"));
}


@Test
public void hiddenParamDoesNotCauseErrors() {
JsonNode parameters = JsonUtils.path(getOpenAPIJson(), "paths./test/example/{userId}.get.parameters");
assertEquals(1, parameters.size());
}
}

0 comments on commit 95e95b5

Please sign in to comment.