public void processOperation( String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations, Path path) { if (operation != null) { if (System.getProperty("debugOperations") != null) { LOGGER.debug( "processOperation: resourcePath= " + resourcePath + "\t;" + httpMethod + " " + operation + "\n"); } List<String> tags = operation.getTags(); if (tags == null) { tags = new ArrayList<String>(); tags.add("default"); } /* build up a set of parameter "ids" defined at the operation level per the swagger 2.0 spec "A unique parameter is defined by a combination of a name and location" i'm assuming "location" == "in" */ Set<String> operationParameters = new HashSet<String>(); if (operation.getParameters() != null) { for (Parameter parameter : operation.getParameters()) { operationParameters.add(generateParameterId(parameter)); } } // need to propagate path level down to the operation if (path.getParameters() != null) { for (Parameter parameter : path.getParameters()) { // skip propagation if a parameter with the same name is already defined at the operation // level if (!operationParameters.contains(generateParameterId(parameter))) { operation.addParameter(parameter); } } } for (String tag : tags) { CodegenOperation co = null; try { co = config.fromOperation( resourcePath, httpMethod, operation, swagger.getDefinitions(), swagger); co.tags = new ArrayList<String>(); co.tags.add(sanitizeTag(tag)); config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations); List<Map<String, List<String>>> securities = operation.getSecurity(); if (securities == null && swagger.getSecurity() != null) { securities = new ArrayList<Map<String, List<String>>>(); for (SecurityRequirement sr : swagger.getSecurity()) { securities.add(sr.getRequirements()); } } if (securities == null || securities.isEmpty()) { continue; } Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>(); // NOTE: Use only the first security requirement for now. // See the "security" field of "Swagger Object": // https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#swagger-object // "there is a logical OR between the security requirements" if (securities.size() > 1) { LOGGER.warn("More than 1 security requirements are found, using only the first one"); } Map<String, List<String>> security = securities.get(0); for (String securityName : security.keySet()) { SecuritySchemeDefinition securityDefinition = fromSecurity(securityName); if (securityDefinition != null) { if (securityDefinition instanceof OAuth2Definition) { OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition; OAuth2Definition oauth2Operation = new OAuth2Definition(); oauth2Operation.setType(oauth2Definition.getType()); oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl()); oauth2Operation.setFlow(oauth2Definition.getFlow()); oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl()); oauth2Operation.setScopes(new HashMap<String, String>()); for (String scope : security.get(securityName)) { if (oauth2Definition.getScopes().containsKey(scope)) { oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope)); } } authMethods.put(securityName, oauth2Operation); } else { authMethods.put(securityName, securityDefinition); } } } if (!authMethods.isEmpty()) { co.authMethods = config.fromSecurity(authMethods); co.hasAuthMethods = true; } } catch (Exception ex) { String msg = "Could not process operation:\n" // + " Tag: " + tag + "\n" // + " Operation: " + operation.getOperationId() + "\n" // + " Resource: " + httpMethod + " " + resourcePath + "\n" // + " Definitions: " + swagger.getDefinitions() + "\n" // + " Exception: " + ex.getMessage(); throw new RuntimeException(msg, ex); } } } }
private void parse( Swagger swagger, RestDefinition rest, String camelContextId, ClassResolver classResolver) { List<VerbDefinition> verbs = new ArrayList<>(rest.getVerbs()); // must sort the verbs by uri so we group them together when an uri has multiple operations Collections.sort(verbs, new VerbOrdering()); // we need to group the operations within the same tag, so use the path as default if not // configured String pathAsTag = rest.getTag() != null ? rest.getTag() : FileUtil.stripLeadingSeparator(rest.getPath()); String summary = rest.getDescriptionText(); if (ObjectHelper.isNotEmpty(pathAsTag)) { // add rest as tag Tag tag = new Tag(); tag.description(summary); tag.name(pathAsTag); swagger.addTag(tag); } // gather all types in use Set<String> types = new LinkedHashSet<>(); for (VerbDefinition verb : verbs) { String type = verb.getType(); if (ObjectHelper.isNotEmpty(type)) { if (type.endsWith("[]")) { type = type.substring(0, type.length() - 2); } types.add(type); } type = verb.getOutType(); if (ObjectHelper.isNotEmpty(type)) { if (type.endsWith("[]")) { type = type.substring(0, type.length() - 2); } types.add(type); } // there can also be types in response messages if (verb.getResponseMsgs() != null) { for (RestOperationResponseMsgDefinition def : verb.getResponseMsgs()) { type = def.getResponseModel(); if (ObjectHelper.isNotEmpty(type)) { if (type.endsWith("[]")) { type = type.substring(0, type.length() - 2); } types.add(type); } } } } // use annotation scanner to find models (annotated classes) for (String type : types) { Class<?> clazz = classResolver.resolveClass(type); appendModels(clazz, swagger); } // used during gathering of apis List<Path> paths = new ArrayList<>(); String basePath = rest.getPath(); for (VerbDefinition verb : verbs) { // the method must be in lower case String method = verb.asVerb().toLowerCase(Locale.US); // operation path is a key String opPath = SwaggerHelper.buildUrl(basePath, verb.getUri()); Operation op = new Operation(); if (ObjectHelper.isNotEmpty(pathAsTag)) { // group in the same tag op.addTag(pathAsTag); } // add id as vendor extensions op.getVendorExtensions().put("x-camelContextId", camelContextId); op.getVendorExtensions().put("x-routeId", verb.getRouteId()); Path path = swagger.getPath(opPath); if (path == null) { path = new Path(); paths.add(path); } path = path.set(method, op); String consumes = verb.getConsumes() != null ? verb.getConsumes() : rest.getConsumes(); if (consumes != null) { String[] parts = consumes.split(","); for (String part : parts) { op.addConsumes(part); } } String produces = verb.getProduces() != null ? verb.getProduces() : rest.getProduces(); if (produces != null) { String[] parts = produces.split(","); for (String part : parts) { op.addProduces(part); } } if (verb.getDescriptionText() != null) { op.summary(verb.getDescriptionText()); } for (RestOperationParamDefinition param : verb.getParams()) { Parameter parameter = null; if (param.getType().equals(RestParamType.body)) { parameter = new BodyParameter(); } else if (param.getType().equals(RestParamType.form)) { parameter = new FormParameter(); } else if (param.getType().equals(RestParamType.header)) { parameter = new HeaderParameter(); } else if (param.getType().equals(RestParamType.path)) { parameter = new PathParameter(); } else if (param.getType().equals(RestParamType.query)) { parameter = new QueryParameter(); } if (parameter != null) { parameter.setName(param.getName()); parameter.setAccess(param.getAccess()); parameter.setDescription(param.getDescription()); parameter.setRequired(param.getRequired()); // set type on parameter if (parameter instanceof SerializableParameter) { SerializableParameter sp = (SerializableParameter) parameter; if (param.getDataType() != null) { sp.setType(param.getDataType()); } if (param.getAllowableValues() != null) { sp.setEnum(param.getAllowableValues()); } } // set schema on body parameter if (parameter instanceof BodyParameter) { BodyParameter bp = (BodyParameter) parameter; if (verb.getType() != null) { String ref = modelTypeAsRef(verb.getType(), swagger); if (ref != null) { bp.setSchema(new RefModel(ref)); } } } op.addParameter(parameter); } } // if we have an out type then set that as response message if (verb.getOutType() != null) { Response response = new Response(); Property prop = modelTypeAsProperty(verb.getOutType(), swagger); response.setSchema(prop); response.setDescription("Output type"); op.addResponse("200", response); } // enrich with configured response messages from the rest-dsl for (RestOperationResponseMsgDefinition msg : verb.getResponseMsgs()) { Response response = null; if (op.getResponses() != null) { response = op.getResponses().get(msg.getCode()); } if (response == null) { response = new Response(); } if (ObjectHelper.isNotEmpty(msg.getResponseModel())) { Property prop = modelTypeAsProperty(msg.getResponseModel(), swagger); response.setSchema(prop); } response.setDescription(msg.getMessage()); op.addResponse(msg.getCode(), response); } // add path swagger.path(opPath, path); } }