operation.setTags(List<String> tags)
It is being cached, yes, but that’s before the filter, not after it – so it’s a bit odd.
Just to take it out of the equation, can you try with the latest version first?
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.
Can you share the filter code?
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
import static org.apache.commons.collections.CollectionUtils.isEmpty;import static org.apache.commons.collections.CollectionUtils.isNotEmpty;import static org.apache.commons.collections.ListUtils.intersection;import static org.apache.commons.collections.MapUtils.isEmpty;import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import io.swagger.core.filter.AbstractSpecFilter;import io.swagger.model.ApiDescription;import io.swagger.models.Operation;
public class SwaggerTagFilterExample extends AbstractSpecFilter {
private static final Logger logger = LoggerFactory.getLogger(SwaggerTagFilterExample.class); private static final String TAG_NAME_ADMIN1 = "Bob"; private static final String TAG_NAME_ADMIN2 = "Carl"; private static final String TAG_NAME_ADMIN3 = "Frank"; private static final String TAG_NAME_ADMIN4 = "Steve"; private static final Set<String> TAG_NAME_SET = new HashSet<String>(); static { TAG_NAME_SET.add(TAG_NAME_ADMIN1); TAG_NAME_SET.add(TAG_NAME_ADMIN2); TAG_NAME_SET.add(TAG_NAME_ADMIN3); TAG_NAME_SET.add(TAG_NAME_ADMIN4); } @Override public boolean isOperationAllowed (Operation operation, ApiDescription api, Map<String, List<String>> paramMap,
Map<String, String> cookies, Map<String, List<String>> headers) { logger.debug("--Entering--"); boolean showOperation = false;
List<String> nameParamList = null; List<String> tagValueList = null; try { // get all the tags from the json tagValueList = operation.getTags(); logger.debug("The tag values are: {}", tagValueList);
nameParamList = getParamList(paramMap, "names"); // apply name filtering logic showOperation = isEmpty(nameParamList) ? true : applyNameFiltering(nameParamList, tagValueList); // remove all name tags for this operation that are not in the nameParamList if (showOperation) { operation.setTags(purgeUnrequestedNameTags(nameParamList, tagValueList)); } } catch (Exception e) { logger.error("Var - nameParamList: {}", nameParamList); logger.error("Var - tagValueList: {}", tagValueList); logger.error("Exception occurred when verifying allowed operations - No swagger operation displayed for you!!"); } logger.debug("--Exiting--"); return showOperation; }
@Override public boolean isRemovingUnreferencedDefinitions() { return true; }
/** * Returns the values from the paramMap that are associated with the paramName key as a List<String>. * * @param paramMap * @param paramName * @return */ private List<String> getParamList(Map<String, List<String>> paramMap, String paramName) { logger.debug("--Entering--"); logger.debug("Var - paramMap: " + (isEmpty(paramMap) ? null : paramMap.toString())); logger.debug("Var - paramName: " + paramName); List<String> paramList = null; try { if (paramMap.containsKey(paramName)) { logger.debug("paramMap.get(paramName).isEmpty() is: {}", paramMap.get(paramName).isEmpty()); if (isNotBlank(paramMap.get(paramName).get(0))) { // get specific tags from the query param paramList = Arrays.asList(paramMap.get(paramName).get(0).split(",")); } logger.debug("The {} params are: {}", paramName, paramList); } } catch (Exception e) { logger.error("Var - paramList: {}", paramList); logger.error("Exception occurred when checking the filter values against the operation tags: {}", e); logger.error("Continuing flow..."); } logger.debug("--Exiting--"); return paramList; }
private final boolean applyNameFiltering(List<String> nameParamList, List<String> tagValueList) { logger.debug("--Entering--"); logger.debug("Var - nameParamList: " + (isEmpty(nameParamList) ? null : nameParamList.toString())); logger.debug("Var - tagValueList: " + (isEmpty(tagValueList) ? null : tagValueList.toString())); boolean matchFound = false; try { if (isNotEmpty(nameParamList) && isNotEmpty(tagValueList)) { matchFound = isNotEmpty(intersection(nameParamList, tagValueList)); } } catch (Exception e) { logger.error("Var - matchFound: {}", matchFound); logger.error("Exception occurred when finding matching name tags: {}", e); logger.error("Continuing flow..."); } logger.debug("--Exiting--"); return matchFound; } /** * Returns a purged list of name tags based upon the master set of name tags while * leaving non-name tags untouched. * * @param nameParamList * @param tagValueList * @return */ private List<String> purgeUnrequestedNameTags(List<String> nameParamList, List<String> tagValueList) {
List<String> cleanNameTagValueList = new ArrayList<String>(); try { if (isEmpty(nameParamList)) { cleanNameTagValueList = tagValueList; } else { for (String tag : tagValueList) { // keep the name if it was passed in as a parameter (in the nameParamList), // but if it is a name tag and was NOT passed in then don't keep it; this also // makes sure that any non-name tags are also kept if (nameParamList.contains(tag) || !TAG_NAME_SET.contains(tag)) { cleanNameTagValueList.add(tag); } } } } catch (Exception e) { logger.error("Var - cleanNameTagValueList: {}", cleanNameTagValueList); logger.error("Exception occurred while purging erroneous name tags: {}", e); logger.error("Continuing flow..."); } logger.debug("--Exiting--"); return cleanNameTagValueList; } }
Thanks for that. Before diving in too much, I see you have debugging logs. When you start the app and issue requests to get the definition, do you see those log lines for each call or only for the first?
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Tuesday, 20 June 2017 at 12:09
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
Sure. I can share all of the codez.
--
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.
There isn’t, but the thing is that the only thing that’s being cached is the initial build of the definition.
So when your app starts up, the scanning will happen, it’ll build the Swagger object, and won’t repeat that process.
Beyond that, every request should be filtered and not cached, which makes your issue odd.
Based on what you describe, it doesn’t seem likely that there’s another proxy in the way that does the caching, as it wouldn’t hit the filter at all… but just to be on the safe side, is there another proxy?
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
Okay, I’m embarrassed now. In my defense, I haven’t touched that in a really long time.
IIRC, the SwaggerSpecFilter will just say – can/cannot see (hence the Boolean operations).
It doesn’t actually allow you to manipulate the spec.
I could be wrong on that account. And I seem to remember there’s still a way to do it, but I might be wrong there too.
I’ll try to find a ‘proper’ way of doing it.
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Tuesday, 20 June 2017 at 13:55
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
No...there isn't. :/
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.
Hi Bryan,
Looking at our previous conversation, in this case you would have to override the ApiListingResource.
That would allow you full control over everything.
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Tuesday, 20 June 2017 at 14:05
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
Thanks for your research Ron...I appreciate it!
On Tuesday, June 20, 2017 at 5:02:38 PM UTC-4, Ron wrote:
Okay, I’m embarrassed now. In my defense, I haven’t touched that in a really long time.
IIRC, the SwaggerSpecFilter will just say – can/cannot see (hence the Boolean operations).
It doesn’t actually allow you to manipulate the spec.
I could be wrong on that account. And I seem to remember there’s still a way to do it, but I might be wrong there too.
I’ll try to find a ‘proper’ way of doing it.
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Tuesday, 20 June 2017 at 13:55
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
No...there isn't. :/
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
The problem is not caching, the problem is that the filter doesn’t let you manipulate content of the spec – it just lets you filter out specific things (operations, paramters…).
The ApiListingResource gives you access to the Swagger object itself, which you can manipulate with whatever logic you want.
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Wednesday, 21 June 2017 at 6:03
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
I've looked back over that previous thread, but I don't follow you.
--
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.
Possibly both, it depends on your logic.
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Wednesday, 21 June 2017 at 13:28
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
Ok, so a couple things here.
First, I have had situations where I have actually removed tags from the operation object and that has been reflected in the response. Which seams to me that the filter is actually manipulating the spec. However, assuming I am wrong on that...let's move on to point two.
Second, are you saying that instead of using the filter at all I would do all of my manipulation in a class that extends ApiListingResource? If that's the case then am I correct in thinking that I would override getListingJsonResponse and manipulate the Swagger object from there in order to achieve all of my filtering? OR...would I use a combination of the filter and the extended ApiListingResource?
On Wednesday, June 21, 2017 at 1:17:04 PM UTC-4, Ron wrote:
The problem is not caching, the problem is that the filter doesn’t let you manipulate content of the spec – it just lets you filter out specific things (operations, paramters…).
The ApiListingResource gives you access to the Swagger object itself, which you can manipulate with whatever logic you want.
From: <swagger-sw...@googlegroups.com> on behalf of Bryan Nelson <bryan.j...@gmail.com>
Reply-To: "swagger-sw...@googlegroups.com" <swagger-sw...@googlegroups.com>
Date: Wednesday, 21 June 2017 at 6:03
To: Swagger <swagger-sw...@googlegroups.com>
Subject: Re: Swagger-Core - Caching of Tag Data in Operations?
I've looked back over that previous thread, but I don't follow you.
I understand how to extend ApiListingResource, but I don't understand how that would help me. How would that help me with the caching issue?
Could you elaborate a bit?
Thanks.
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
The method process(Application, ServletContext, ServletConfig, HttpHeaders, UriInfo) from the type BaseApiListingResource is not visible
import static org.apache.commons.collections.CollectionUtils.isEmpty;import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList;
import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;
import javax.servlet.ServletConfig;import javax.servlet.ServletContext;import javax.ws.rs.GET;import javax.ws.rs.PathParam;import javax.ws.rs.Produces;import javax.ws.rs.core.Application;import javax.ws.rs.core.Context;import javax.ws.rs.core.HttpHeaders;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.MultivaluedMap;import javax.ws.rs.core.Response;import javax.ws.rs.core.UriInfo;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import io.swagger.annotations.ApiOperation;import io.swagger.jaxrs.listing.ApiListingResource;import io.swagger.models.Swagger;import io.swagger.models.Tag;import io.swagger.models.Operation;import io.swagger.models.Path;import io.swagger.util.Json;
@javax.ws.rs.Path("/internal/swagger/{type:json|yaml}")public class SwaggerTagFilterResourceExample extends ApiListingResource {
private static final Logger logger = LoggerFactory.getLogger(SwaggerTagFilterResourceExample.class);
private static final String TAG_NAME_ADMIN1 = "Bob"; private static final String TAG_NAME_ADMIN2 = "Carl"; private static final String TAG_NAME_ADMIN3 = "Frank"; private static final String TAG_NAME_ADMIN4 = "Steve"; private static final Set<String> TAG_NAME_SET = new HashSet<String>(); static { TAG_NAME_SET.add(TAG_NAME_ADMIN1); TAG_NAME_SET.add(TAG_NAME_ADMIN2); TAG_NAME_SET.add(TAG_NAME_ADMIN3); TAG_NAME_SET.add(TAG_NAME_ADMIN4); }
@Context ServletContext context;
@GET @Produces({MediaType.APPLICATION_JSON, "application/yaml"}) @ApiOperation(value = "The swagger definition in either JSON or YAML", hidden = true) public Response getListing(@Context Application app, @Context ServletConfig servletConfig, @Context HttpHeaders headers, @Context UriInfo uriInfo, @PathParam("type") String type) { if (isNotBlank(type) && type.trim().equalsIgnoreCase("yaml")) { logger.debug("Creating Swagger YAML..."); return getListingYamlResponse(app, context, servletConfig, headers, uriInfo); } else { logger.debug("Creating Swagger JSON..."); return getListingJsonResponse(app, context, servletConfig, headers, uriInfo); } } protected Response getListingJsonResponse( Application app, ServletContext servletContext, ServletConfig servletConfig, HttpHeaders headers, UriInfo uriInfo) { Swagger swagger = process(app, servletContext, servletConfig, headers, uriInfo);
MultivaluedMap<String, String> queryParamMultivaluedMap = uriInfo.getQueryParameters(); List<Tag> tagList = swagger.getTags(); Map<String, Path> pathMap = swagger.getPaths(); List<Tag> newTagList = new ArrayList<Tag>(); List<String> newStringTagList = new ArrayList<String>(); for (MultivaluedMap.Entry<String, List<String>> entry : queryParamMultivaluedMap.entrySet()) { if (entry.getKey().equalsIgnoreCase("names") && isNotEmpty(entry.getValue())) { // remove all name tags from the top level Swagger object that are not in the names query parameter list swagger.setTags(purgeUnrequestedNameTags(entry.getValue(), tagList)); // remove all name tags from each Operation object that are not in the names query parameter list for (Path path : pathMap.values()) { List<Operation> operationList = path.getOperations(); for (Operation operation : operationList) { newTagList = purgeUnrequestedNameTags(entry.getValue(), tagList); for (Tag tag : newTagList) { newStringTagList.add(tag.getName()); } operation.setTags(newStringTagList); } } } } if (swagger != null) { return Response.ok().entity(Json.mapper().writeValueAsString(swagger)).type(MediaType.APPLICATION_JSON_TYPE).build(); } else { return Response.status(404).build();
} } /** * Returns a purged list of name tags based upon the master set of name tags while * leaving non-name tags untouched. * * @param nameParamList * @param tagValueList * @return */
private List<Tag> purgeUnrequestedNameTags(List<String> nameParamList, List<Tag> tagValueList) {
List<Tag> cleanNameTagValueList = new ArrayList<Tag>();
try { if (isEmpty(nameParamList)) { cleanNameTagValueList = tagValueList; } else {
for (Tag tag : tagValueList) {
// keep the name if it was passed in as a parameter (in the nameParamList), // but if it is a name tag and was NOT passed in then don't keep it; this also // makes sure that any non-name tags are also kept
if (nameParamList.contains(tag.getName()) || !TAG_NAME_SET.contains(tag.getName())) {
cleanNameTagValueList.add(tag); } } } } catch (Exception e) { logger.error("Var - cleanNameTagValueList: {}", cleanNameTagValueList); logger.error("Exception occurred while purging erroneous name tags: {}", e); logger.error("Continuing flow..."); } logger.debug("--Exiting--"); return cleanNameTagValueList; }}