14

Tôi đang xây dựng một ứng dụng bằng cách sử dụng các dịch vụ nhỏ với ngăn xếp netflix và khởi động mùa xuân. Một điều khiến tôi bị lỗi là tôi chưa có thử nghiệm tích hợp, nơi tôi có thể thử các dịch vụ xung quanh.Dịch vụ thử nghiệm sử dụng eureka và ribbon

Vì vậy, tôi có dịch vụ A là ứng dụng khách eureka có dải băng để phân giải tên eureka thành URL của dịch vụ đã đăng ký B trong khi gọi. Vì vậy, lý tưởng là tôi muốn khởi động ứng dụng với các chú thích tích hợp của khởi động mùa xuân, sử dụng wiremock để mô phỏng dịch vụ B và sau đó gọi phương thức dịch vụ A, điều này sẽ gọi dịch vụ giả mạo B của tôi bằng cách sử dụng tên biểu tượng của dịch vụ .

Có ai đã giải quyết vấn đề này không? Tôi đã tìm kiếm các mục nhập blog ... của những người đã thực hiện việc này, nhưng không thể tìm thấy bất kỳ ...

Tôi biết bài viết SO Mock an Eureka Feign Client for Unittesting nhưng theo tôi thấy điều này chỉ ngăn khách hàng khám phá phàn nàn.

+0

bài này thảo luận về một số phương pháp khác nhau: https://opencredo.com/working-locally-with-microservices/ – MarkOfHall

+0

Hình như bài báo chỉ nói về những điều cơ bản và được viết bằng một mức độ cao. Các cách tiếp cận khá rõ ràng, tôi quan tâm hơn nếu ai đó tìm thấy một cách hay để thực sự làm điều này. Cách tiếp cận mã khỉ ninja được đề cập là một cách, nhưng điều này vẫn đòi hỏi tôi phải đảo ngược kỹ sư và duy trì "eureka giả" ... –

Trả lời

5

Mã sau (được lấy từ https://github.com/Netflix/eureka/blob/a7a8d278e6399bbff5faa49b9fcbcd7ea9e854f4/eureka-core/src/test/java/com/netflix/eureka/mock/MockRemoteEurekaServer.java) có thể hữu ích cho bạn;

public class MockRemoteEurekaServer extends ExternalResource { 

public static final String EUREKA_API_BASE_PATH = "/eureka/v2/"; 

private final Map<String, Application> applicationMap; 
private final Map<String, Application> applicationDeltaMap; 
private final Server server; 
private boolean sentDelta; 
private int port; 
private volatile boolean simulateNotReady; 

public MockRemoteEurekaServer(int port, Map<String, Application> applicationMap, 
           Map<String, Application> applicationDeltaMap) { 
    this.applicationMap = applicationMap; 
    this.applicationDeltaMap = applicationDeltaMap; 
    ServletHandler handler = new AppsResourceHandler(); 
    EurekaServerConfig serverConfig = new DefaultEurekaServerConfig(); 
    EurekaServerContext serverContext = mock(EurekaServerContext.class); 
    when(serverContext.getServerConfig()).thenReturn(serverConfig); 

    handler.addFilterWithMapping(ServerRequestAuthFilter.class, "/*", 1).setFilter(new ServerRequestAuthFilter(serverContext)); 
    handler.addFilterWithMapping(RateLimitingFilter.class, "/*", 1).setFilter(new RateLimitingFilter(serverContext)); 
    server = new Server(port); 
    server.addHandler(handler); 
    System.out.println(String.format(
      "Created eureka server mock with applications map %s and applications delta map %s", 
      stringifyAppMap(applicationMap), stringifyAppMap(applicationDeltaMap))); 
} 

@Override 
protected void before() throws Throwable { 
    start(); 
} 

@Override 
protected void after() { 
    try { 
     stop(); 
    } catch (Exception e) { 
     Assert.fail(e.getMessage()); 
    } 
} 

public void start() throws Exception { 
    server.start(); 
    port = server.getConnectors()[0].getLocalPort(); 
} 

public void stop() throws Exception { 
    server.stop(); 
} 

public boolean isSentDelta() { 
    return sentDelta; 
} 

public int getPort() { 
    return port; 
} 

public void simulateNotReady(boolean simulateNotReady) { 
    this.simulateNotReady = simulateNotReady; 
} 

private static String stringifyAppMap(Map<String, Application> applicationMap) { 
    StringBuilder builder = new StringBuilder(); 
    for (Map.Entry<String, Application> entry : applicationMap.entrySet()) { 
     String entryAsString = String.format("{ name : %s , instance count: %d }", entry.getKey(), 
       entry.getValue().getInstances().size()); 
     builder.append(entryAsString); 
    } 
    return builder.toString(); 
} 

private class AppsResourceHandler extends ServletHandler { 

    @Override 
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) 
      throws IOException, ServletException { 

     if (simulateNotReady) { 
      response.setStatus(HttpServletResponse.SC_FORBIDDEN); 
      return; 
     } 
     String authName = request.getHeader(AbstractEurekaIdentity.AUTH_NAME_HEADER_KEY); 
     String authVersion = request.getHeader(AbstractEurekaIdentity.AUTH_VERSION_HEADER_KEY); 
     String authId = request.getHeader(AbstractEurekaIdentity.AUTH_ID_HEADER_KEY); 

     Assert.assertNotNull(authName); 
     Assert.assertNotNull(authVersion); 
     Assert.assertNotNull(authId); 

     Assert.assertTrue(!authName.equals(ServerRequestAuthFilter.UNKNOWN)); 
     Assert.assertTrue(!authVersion.equals(ServerRequestAuthFilter.UNKNOWN)); 
     Assert.assertTrue(!authId.equals(ServerRequestAuthFilter.UNKNOWN)); 

     for (FilterHolder filterHolder : this.getFilters()) { 
      filterHolder.getFilter().doFilter(request, response, new FilterChain() { 
       @Override 
       public void doFilter(ServletRequest request, ServletResponse response) 
         throws IOException, ServletException { 
        // do nothing; 
       } 
      }); 
     } 

     String pathInfo = request.getPathInfo(); 
     System.out.println(
       "Eureka resource mock, received request on path: " + pathInfo + ". HTTP method: |" + request 
         .getMethod() + '|'); 
     boolean handled = false; 
     if (null != pathInfo && pathInfo.startsWith("")) { 
      pathInfo = pathInfo.substring(EUREKA_API_BASE_PATH.length()); 
      if (pathInfo.startsWith("apps/delta")) { 
       Applications apps = new Applications(); 
       for (Application application : applicationDeltaMap.values()) { 
        apps.addApplication(application); 
       } 
       apps.setAppsHashCode(apps.getReconcileHashCode()); 
       sendOkResponseWithContent((Request) request, response, toJson(apps)); 
       handled = true; 
       sentDelta = true; 
      } else if (pathInfo.startsWith("apps")) { 
       Applications apps = new Applications(); 
       for (Application application : applicationMap.values()) { 
        apps.addApplication(application); 
       } 
       apps.setAppsHashCode(apps.getReconcileHashCode()); 
       sendOkResponseWithContent((Request) request, response, toJson(apps)); 
       handled = true; 
      } 
     } 

     if (!handled) { 
      response.sendError(HttpServletResponse.SC_NOT_FOUND, 
        "Request path: " + pathInfo + " not supported by eureka resource mock."); 
     } 
    } 

    private void sendOkResponseWithContent(Request request, HttpServletResponse response, String content) 
      throws IOException { 
     response.setContentType("application/json; charset=UTF-8"); 
     response.setStatus(HttpServletResponse.SC_OK); 
     response.getOutputStream().write(content.getBytes("UTF-8")); 
     response.getOutputStream().flush(); 
     request.setHandled(true); 
     System.out.println("Eureka resource mock, sent response for request path: " + request.getPathInfo() + 
       " with content" + content); 
    } 
} 

private String toJson(Applications apps) throws IOException { 
    return new EurekaJsonJacksonCodec().getObjectMapper(Applications.class).writeValueAsString(apps); 
} 

} 
+1

Trong tương lai, đừng sao chép nội dung từ nơi khác mà không phân bổ rõ ràng. Nó được xem là đạo văn. Xem http://stackoverflow.com/help/referencing – Matt

5

Một tùy chọn sẽ là sử dụng Camel để giả lập/thay thế các điểm cuối Eureka. Nên có cấu hình nói cho ứng dụng của bạn tìm kiếm Eureka ở đâu, vì vậy hãy ghi đè lên trong cấu hình thử nghiệm của bạn để trỏ đến điểm cuối mới.

Sau đó tạo tuyến đường Camel trong thử nghiệm/src bằng cách sử dụng cầu nối hoặc http để biểu diễn điểm cuối mới này, sẽ trả về phản hồi mà LoadBalancerClient mong đợi. Phản hồi đó sẽ có URI được kiểm tra (ví dụ: ứng dụng của bạn).

Các vấn đề liên quan