Как «удалить префикс gobal ('/ api'), а затем перейти на lb: //» при переходе на весенний облачный шлюз из zuul - PullRequest
0 голосов
/ 09 января 2019

Я хочу перейти с zuul на весенний облачный шлюз, я не хочу менять конфигурацию предыдущего приложения. Я хочу знать, как справиться с URL с "/ api / + 'serviceId'", маршрут к lb: // serviceId

предыдущий конфиг zuul

zuul: 
  prefix: /api

существует множество сервисных реестров для eureka, я не хочу настраивать маршрут для каждого из них.

например. автоматически созданный маршрут с помощью org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator

{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
  "id": "CompositeDiscoveryClient_APIGATEWAY",
  "predicates": [
    {
      "name": "Path",
      "args": {
        "pattern": "/apigateway/**"
      }
    }
  ],
  "filters": [
    {
      "name": "RewritePath",
      "args": {
        "regexp": "/apigateway/(?<remaining>.*)",
        "replacement": "/${remaining}"
      }
    }
  ],
  "uri": "lb://APIGATEWAY",
  "order": 0
}

что я хотел, это

 {
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
  "id": "CompositeDiscoveryClient_APIGATEWAY",
  "predicates": [
    {
      "name": "Path",
      "args": {
        "pattern": "/api/apigateway/**"
      }
    }
  ],
  "filters": [
    {
      "name": "RewritePath",
      "args": {
        "regexp": "/api/apigateway/(?<remaining>.*)",
        "replacement": "/${remaining}"
      }
    }
  ],
  "uri": "lb://APIGATEWAY",
  "order": 0
}

как я могу настроить свой маршрут, чтобы получить то, что я хочу

И я также нашел исходный код

    public static List<PredicateDefinition> initPredicates() {
    ArrayList<PredicateDefinition> definitions = new ArrayList<>();
    // TODO: add a predicate that matches the url at /serviceId?

    // add a predicate that matches the url at /serviceId/**
    PredicateDefinition predicate = new PredicateDefinition();
    predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
    predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
    definitions.add(predicate);
    return definitions;
}

"'/' + serviceId + '/ **'" там без префикса

[2019-01-10] ОБНОВЛЕНИЕ Я думаю, что предложение @ spencergibb является хорошим решением, но у меня возникли новые проблемы с (SpEL) Я пробовал много способов:

args:
  regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
  replacement: '/${remaining}'
args:
  regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
  replacement: "'/${remaining}'"

старт не удался

Origin: class path resource [application.properties]:23:70
Reason: Could not resolve placeholder 'remaining' in value "'${remaining}'"

когда я использую escape "\" как

args:
  regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
  replacement: '/$\{remaining}'

это начало успешно, но я получил исключение при запуске

org.springframework.expression.spel.SpelParseException: Expression [/$\{remaining}] @2: EL1065E: unexpected escape character.
at org.springframework.expression.spel.standard.Tokenizer.raiseParseException(Tokenizer.java:590) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.expression.spel.standard.Tokenizer.process(Tokenizer.java:265) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]



ОБНОВЛЕНИЕ 2

Я нашел в org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory, есть замена, чтобы иметь дело с "\"

...    
@Override
        public GatewayFilter apply(Config config) {
            String replacement = config.replacement.replace("$\\", "$");
            return (exchange, chain) -> {
...

когда дело доходит до SpelParseException нет ни одного

1 Ответ

0 голосов
/ 09 января 2019

Вы можете настроить автоматические фильтры и предикаты, используемые через свойства.

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          predicates:
            - name: Path
              args:
                pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
          filters:
            - name: RewritePath
              args:
                regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
                replacement: "'/${remaining}'"

Обратите внимание, что значения (т. Е. args.pattern или args.regexp) - это все выражения Spring Expression Language (SpEL), следовательно, одинарные кавычки и + etc ...

Если разные маршруты должны иметь разные префиксы, вам нужно определить каждый маршрут в свойствах.

...