mirror of
https://github.com/google/nomulus.git
synced 2025-05-12 22:38:16 +02:00
Add golden files for request component routing maps
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=157026188
This commit is contained in:
parent
bb67841884
commit
ddb0f5692e
23 changed files with 514 additions and 39 deletions
169
java/google/registry/request/RouterDisplayHelper.java
Normal file
169
java/google/registry/request/RouterDisplayHelper.java
Normal file
|
@ -0,0 +1,169 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.request;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class to help in dumping routing maps.
|
||||
*
|
||||
* <p>Each of the App Engine services (frontend, backend, and tools) has a Dagger component used for
|
||||
* routing requests (e.g. FrontendRequestComponent). This class produces a text file representation
|
||||
* of the routing configuration, showing what paths map to what action classes, as well as the
|
||||
* properties of the action classes' annotations (which cover things like allowable HTTP methods,
|
||||
* authentication settings, etc.). The text file can be useful for documentation, and is also used
|
||||
* in unit tests to check against golden routing maps to find possibly unexpected changes.
|
||||
*
|
||||
* <p>The file has fixed-width columns with a header row. The width of the columns is determined by
|
||||
* the content to be displayed. The columns are:
|
||||
*
|
||||
* <ol>
|
||||
* <li>the URL path which maps to this action (with a "(*)" after it if the prefix flag is set)
|
||||
* <li>the simple name of the action class
|
||||
* <li>the allowable HTTP methods
|
||||
* <li>whether to automatically print "ok" in the response
|
||||
* <li>whether XSRF protection is enabled
|
||||
* <li>the XSRF scope
|
||||
* <li>whether login is required
|
||||
* <li>the allowable authentication methods
|
||||
* <li>the minimum authentication level
|
||||
* <li>the user policy
|
||||
* </ol>
|
||||
*
|
||||
* <p>See the Auth class for more information about authentication settings.
|
||||
*/
|
||||
public class RouterDisplayHelper {
|
||||
|
||||
private static final String PATH = "path";
|
||||
private static final String CLASS = "class";
|
||||
private static final String METHODS = "methods";
|
||||
private static final String XSRF_SCOPE = "xsrfScope";
|
||||
private static final String AUTH_METHODS = "authMethods";
|
||||
private static final String MINIMUM_LEVEL = "minLevel";
|
||||
|
||||
private static final String FORMAT =
|
||||
"%%-%ds %%-%ds %%-%ds %%-2s %%-4s %%-%ds %%-5s %%-%ds %%-%ds %%s";
|
||||
|
||||
/** Returns a string representation of the routing map in the specified component. */
|
||||
public static String extractHumanReadableRoutesFromComponent(Class<?> componentClass) {
|
||||
return formatRoutes(Router.extractRoutesFromComponent(componentClass).values());
|
||||
}
|
||||
|
||||
private static String getFormatString(Map<String, Integer> columnWidths) {
|
||||
return String.format(
|
||||
FORMAT,
|
||||
columnWidths.get(PATH),
|
||||
columnWidths.get(CLASS),
|
||||
columnWidths.get(METHODS),
|
||||
columnWidths.get(XSRF_SCOPE),
|
||||
columnWidths.get(AUTH_METHODS),
|
||||
columnWidths.get(MINIMUM_LEVEL));
|
||||
}
|
||||
|
||||
private static String headerToString(String formatString) {
|
||||
return String.format(
|
||||
formatString,
|
||||
"PATH",
|
||||
"CLASS",
|
||||
"METHODS",
|
||||
"OK",
|
||||
"XSRF",
|
||||
"SCOPE",
|
||||
"LOGIN",
|
||||
"AUTH_METHODS",
|
||||
"MIN",
|
||||
"USER_POLICY");
|
||||
}
|
||||
|
||||
private static String routeToString(Route route, String formatString) {
|
||||
return String.format(
|
||||
formatString,
|
||||
route.action().isPrefix() ? (route.action().path() + "(*)") : route.action().path(),
|
||||
route.actionClass().getSimpleName(),
|
||||
Joiner.on(",").join(route.action().method()),
|
||||
route.action().automaticallyPrintOk() ? "y" : "n",
|
||||
route.action().xsrfProtection() ? "y" : "n",
|
||||
route.action().xsrfScope(),
|
||||
route.action().requireLogin() ? "y" : "n",
|
||||
Joiner.on(",").join(route.action().auth().methods()),
|
||||
route.action().auth().minimumLevel(),
|
||||
route.action().auth().userPolicy());
|
||||
}
|
||||
|
||||
private static String formatRoutes(Iterable<Route> routes) {
|
||||
|
||||
// Use the column header length as a minimum.
|
||||
int pathWidth = 4;
|
||||
int classWidth = 5;
|
||||
int methodsWidth = 7;
|
||||
int xsrfScopeWidth = 5;
|
||||
int authMethodsWidth = 12;
|
||||
int minLevelWidth = 3;
|
||||
for (Route route : routes) {
|
||||
int len =
|
||||
route.action().isPrefix()
|
||||
? (route.action().path().length() + 3)
|
||||
: route.action().path().length();
|
||||
if (len > pathWidth) {
|
||||
pathWidth = len;
|
||||
}
|
||||
len = route.actionClass().getSimpleName().length();
|
||||
if (len > classWidth) {
|
||||
classWidth = len;
|
||||
}
|
||||
len = Joiner.on(",").join(route.action().method()).length();
|
||||
if (len > methodsWidth) {
|
||||
methodsWidth = len;
|
||||
}
|
||||
len = route.action().xsrfScope().length();
|
||||
if (len > xsrfScopeWidth) {
|
||||
xsrfScopeWidth = len;
|
||||
}
|
||||
len = Joiner.on(",").join(route.action().auth().methods()).length();
|
||||
if (len > authMethodsWidth) {
|
||||
authMethodsWidth = len;
|
||||
}
|
||||
len = route.action().auth().minimumLevel().toString().length();
|
||||
if (len > minLevelWidth) {
|
||||
minLevelWidth = len;
|
||||
}
|
||||
}
|
||||
final String formatString =
|
||||
getFormatString(
|
||||
new ImmutableMap.Builder<String, Integer>()
|
||||
.put(PATH, pathWidth)
|
||||
.put(CLASS, classWidth)
|
||||
.put(METHODS, methodsWidth)
|
||||
.put(XSRF_SCOPE, xsrfScopeWidth)
|
||||
.put(AUTH_METHODS, authMethodsWidth)
|
||||
.put(MINIMUM_LEVEL, minLevelWidth)
|
||||
.build());
|
||||
return headerToString(formatString)
|
||||
+ String.format("%n")
|
||||
+ FluentIterable.from(routes)
|
||||
.transform(
|
||||
new Function<Route, String>() {
|
||||
@Override
|
||||
public String apply(Route route) {
|
||||
return routeToString(route, formatString);
|
||||
}
|
||||
})
|
||||
.join(Joiner.on(String.format("%n")));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue