/** * Delivers the primary REST method associated with the given RPC method. Returns null * if the method has no HTTP attribute. */ @Nullable public static RestMethod getPrimaryRestMethod(Method method) { HttpAttribute attrib = method.getAttribute(HttpAttribute.KEY); if (attrib == null) { return null; } return attrib.getRestMethod(); }
/** * Delivers the primary REST method associated with the given RPC method. Returns null * if the method has no HTTP attribute. */ @Nullable public static RestMethod getPrimaryRestMethod(Method method) { HttpAttribute attrib = method.getAttribute(HttpAttribute.KEY); if (attrib == null) { return null; } return attrib.getRestMethod(); }
/** Returns a list of CollectionPattern objects. */ public static List<CollectionPattern> getCollectionPatternsFromMethod(Method method) { List<CollectionPattern> collectionPatterns = new LinkedList<CollectionPattern>(); HttpAttribute httpAttr = method.getAttribute(HttpAttribute.KEY); if (httpAttr != null) { for (PathSegment pathSegment : httpAttr.getPath()) { if (CollectionPattern.isValidCollectionPattern(pathSegment)) { collectionPatterns.add(CollectionPattern.create((FieldSegment) pathSegment)); } } } return collectionPatterns; }
@Override public boolean isIdempotent() { HttpAttribute httpAttr = method.getAttribute(HttpAttribute.KEY); if (httpAttr == null) { return false; } MethodKind methodKind = httpAttr.getMethodKind(); return methodKind.isIdempotent(); }
@SuppressWarnings("deprecation") private String deriveApiVersion(Method element) { // Derive the version from the prefix of the http path. Validation of // syntax of version in path happens elsewhere, so we take just the first path segment // literal. If none is given, assume 'v1'. HttpAttribute http = element.getAttribute(HttpAttribute.KEY); if (http == null || http.getPath().isEmpty() || !(http.getPath().get(0) instanceof LiteralSegment)) { return "v1"; } return ((LiteralSegment) http.getPath().get(0)).getLiteral(); }
@SuppressWarnings("deprecation") private String deriveApiVersion(Method element) { // Derive the version from the prefix of the http path. Validation of // syntax of version in path happens elsewhere, so we take just the first path segment // literal. If none is given, assume 'v1'. HttpAttribute http = element.getAttribute(HttpAttribute.KEY); if (http == null || http.getPath().isEmpty() || !(http.getPath().get(0) instanceof LiteralSegment)) { return "v1"; } return ((LiteralSegment) http.getPath().get(0)).getLiteral(); }
private void deriveDoc(Method redeclared, Method method) { String doc = DocumentationUtil.getScopedDescription(redeclared); if (!whitespace().matchesAllOf(Strings.nullToEmpty((doc)))) { // Don't derive as it is overridden. return; } ElementDocumentationAttribute sourceAttrib = method.getAttribute(ElementDocumentationAttribute.KEY); if (sourceAttrib != null) { redeclared.putAttribute(ElementDocumentationAttribute.KEY, sourceAttrib); } }
private static Set<String> calculateRestVersions(Method method) { Set<String> restVersions = Sets.newHashSet(); if (!method.hasAttribute(HttpAttribute.KEY)) { // Return an empty set if the proto method doesn't have http binding. return restVersions; } // Exclude rest version introduced by System APIs. for (String prefix : ConfigRuleSet.SYSTEM_PROTO_PREFIXES) { if (method.getFullName().startsWith(prefix)) { return Collections.emptySet(); } } for (HttpAttribute binding : method.getAttribute(HttpAttribute.KEY).getAllBindings()) { restVersions.add(binding.getRestMethod().getVersionWithDefault()); } return restVersions; } }
private void deriveDoc(Method redeclared, Method method) { String doc = DocumentationUtil.getScopedDescription(redeclared); if (!whitespace().matchesAllOf(Strings.nullToEmpty((doc)))) { // Don't derive as it is overridden. return; } ElementDocumentationAttribute sourceAttrib = method.getAttribute(ElementDocumentationAttribute.KEY); if (sourceAttrib != null) { redeclared.putAttribute(ElementDocumentationAttribute.KEY, sourceAttrib); } }
private static Set<String> calculateRestVersions(Method method) { Set<String> restVersions = Sets.newHashSet(); if (!method.hasAttribute(HttpAttribute.KEY)) { // Return an empty set if the proto method doesn't have http binding. return restVersions; } // Exclude rest version introduced by System APIs. for (String prefix : ConfigRuleSet.SYSTEM_PROTO_PREFIXES) { if (method.getFullName().startsWith(prefix)) { return Collections.emptySet(); } } for (HttpAttribute binding : method.getAttribute(HttpAttribute.KEY).getAllBindings()) { restVersions.add(binding.getRestMethod().getVersionWithDefault()); } return restVersions; } }
/** * Return the list of API versions for all reachable API methods. */ public static List<String> getReachableRestVersions(Model model) { Set<String> versions = Sets.newLinkedHashSet(); for (Interface iface : model.getSymbolTable().getInterfaces()) { for (Method method : iface.getReachableMethods()) { if (method.hasAttribute(HttpAttribute.KEY)) { for (HttpAttribute binding : method.getAttribute(HttpAttribute.KEY).getAllBindings()) { versions.add(binding.getRestMethod().getVersionWithDefault()); } } } } List<String> versionsList = Lists.newArrayList(versions); Collections.sort(versionsList, Collections.reverseOrder(new VersionComparator())); return versionsList; } }
/** * Return the list of API versions for all reachable API methods. */ public static List<String> getReachableRestVersions(Model model) { Set<String> versions = Sets.newLinkedHashSet(); for (Interface iface : model.getSymbolTable().getInterfaces()) { for (Method method : iface.getReachableMethods()) { if (method.hasAttribute(HttpAttribute.KEY)) { for (HttpAttribute binding : method.getAttribute(HttpAttribute.KEY).getAllBindings()) { versions.add(binding.getRestMethod().getVersionWithDefault()); } } } } List<String> versionsList = Lists.newArrayList(versions); Collections.sort(versionsList, Collections.reverseOrder(new VersionComparator())); return versionsList; } }
@Override public void run(Method method) { if (!method.hasAttribute(HttpAttribute.KEY)) { return; } Set<String> visitedFieldNames = Sets.newHashSet(); for (HttpAttribute httpAttribute : method.getAttribute(HttpAttribute.KEY).getAllBindings()) { for (FieldSelector fieldSelector : httpAttribute.getParamSelectors()) { String restParameterName = fieldSelector.getLastField().getJsonName(); if (!visitedFieldNames.contains(restParameterName)) { visitedFieldNames.add(restParameterName); if (SystemParameter.isSystemParameter(restParameterName)) { warning( method.getLocation(), "Field name '%s' is a reserved keyword, please use a different name. " + "The reserved keywords are %s.", restParameterName, Joiner.on(", ").join(SystemParameter.allSystemParameters()).toLowerCase()); } } } } } }
@Override public void run(Method method) { HttpAttribute binding = method.getAttribute(HttpAttribute.KEY); if (binding != null) { validate(method, binding); for (HttpAttribute additionalBinding : binding.getAdditionalBindings()) { validateAdditionalBindingConstraints(method, additionalBinding.getHttpRule()); validate(method, additionalBinding); } } }
@Override public void run(Method method) { HttpAttribute binding = method.getAttribute(HttpAttribute.KEY); if (binding != null) { validate(method, binding); for (HttpAttribute additionalBinding : binding.getAdditionalBindings()) { validateAdditionalBindingConstraints(method, additionalBinding.getHttpRule()); validate(method, additionalBinding); } } }
/** * Returns the body type iff the body associates with exactly one message type. * Otherwise, returns null. */ @Nullable private TypeRef getSingleBodyType(Method method) { HttpAttribute httpConfig = method.getAttribute(HttpAttribute.KEY); if (httpConfig == null) { return null; } if (!httpConfig.bodyCapturesUnboundFields() && httpConfig.getBodySelectors().size() == 1) { TypeRef type = httpConfig.getBodySelectors().get(0).getType(); if (type.isMessage()) { // Get the TypeRef of the declared MessageType that is referenced in the body // selector field. // TODO(user): If it is common use pattern, consider moving it to where it belongs. return model.getSymbolTable().lookupType(type.getMessageType().getFullName()); } } return null; }
/** * Returns the body type iff the body associates with exactly one message type. * Otherwise, returns null. */ @Nullable private TypeRef getSingleBodyType(Method method) { HttpAttribute httpConfig = method.getAttribute(HttpAttribute.KEY); if (httpConfig == null) { return null; } if (!httpConfig.bodyCapturesUnboundFields() && httpConfig.getBodySelectors().size() == 1) { TypeRef type = httpConfig.getBodySelectors().get(0).getType(); if (type.isMessage()) { // Get the TypeRef of the declared MessageType that is referenced in the body // selector field. // TODO(user): If it is common use pattern, consider moving it to where it belongs. return model.getSymbolTable().lookupType(type.getMessageType().getFullName()); } } return null; }
@Test public void mergesWithYamlConfig() throws Exception { createApi("service.proto", "included_type.proto"); model.setConfigSources( testConfig.getApiYamlConfigSources( model.getDiagReporter().getDiagCollector(), ImmutableList.of("service.yaml"))); StandardSetup.registerStandardConfigAspects(model); model.establishStage(Merged.KEY); checkNoErrors(); Method getBucket = getMethod("protiary.test.Storage", "GetBucket"); Assert.assertEquals("Override GetBucket documentation.", getBucket.getAttribute(ElementDocumentationAttribute.KEY).documentation()); assertTypeInclusions(model, Lists.newArrayList("protiary.test.inclusion.Type1", "protiary.test.inclusion.Type2", "protiary.test.inclusion.Enum1"), Lists.newArrayList("protiary.test.inclusion.Type3")); }
private void assertMethodConfig(String interfaceName, String methodName, MethodKind kind, ImmutableSet<String> pathSelectors, ImmutableSet<String> paramSelectors, ImmutableSet<String> bodySelectors) { Method method = getMethod(interfaceName, methodName); HttpAttribute binding = method.getAttribute(HttpAttribute.KEY); Assert.assertNotNull(binding); Assert.assertEquals(kind, binding.getMethodKind()); Assert.assertEquals(pathSelectors, selectors(binding.getPathSelectors())); Assert.assertEquals(paramSelectors, selectors(binding.getParamSelectors())); Assert.assertEquals(bodySelectors, selectors(binding.getBodySelectors())); }
@Test public void mergesWithConfig() throws Exception { createApi("service.proto"); model.setServiceConfig(testConfig.getApiProtoConfig("service.config")); StandardSetup.registerStandardConfigAspects(model); model.establishStage(Merged.KEY); checkNoErrors(); Interface iface = getInterface("protiary.test.Storage"); Method getBucket = getMethod("protiary.test.Storage", "GetBucket"); Assert.assertEquals("v1", iface.getAttribute(VersionAttribute.KEY).majorVersion()); Assert.assertEquals("Get Bucket. (-- For internal tests --)", getBucket.getAttribute(ElementDocumentationAttribute.KEY).documentation()); }