/** * Test that an open circuit is closed after 1 success. This also ensures that the rolling window * (containing failures) is cleared after the sleep window Otherwise, the next bucket roll would * produce another signal to fail unless it is explicitly cleared (via {@link * HystrixCommandMetrics#resetStream()}. */ @Test public void testCircuitClosedAfterSuccess() { String key = "cmd-G"; try { int sleepWindow = 20; HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 1, sleepWindow); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); cmd1.execute(); HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key, sleepWindow); cmd4.execute(); // everything has failed in the test window so we should return false now Thread.sleep(100); System.out.println( "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString()); System.out.println("CircuitBreaker state 1 : " + cmd1.getMetrics().getHealthCounts()); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); // wait for sleepWindow to pass Thread.sleep(sleepWindow + 50); // but the circuit should still be open assertTrue(cb.isOpen()); // we should now allow 1 request, and upon success, should cause the circuit to be closed HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 60, sleepWindow); Observable<Boolean> asyncResult = cmd5.observe(); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); asyncResult.toBlocking().single(); // all requests should be open again System.out.println("CircuitBreaker state 2 : " + cmd1.getMetrics().getHealthCounts()); assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); // and the circuit should be closed again assertFalse(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
@Test public void createFailsValidation() { Identity identity = new Identity(UUID.randomUUID()); ProfileContact contact = new ProfileContact(1, "email", new DefaultContactData("a@"), true); ProfileContacts contacts = new ProfileContacts(Lists.newArrayList(contact)); Observable<Result> result = service.create(identity, contacts); assertEquals(Result.withClientCause("Invalid Contacts"), result.toBlocking().first()); }
@Test public void createWithValidInput() { Identity identity = new Identity(UUID.randomUUID()); ProfileContact contact = new ProfileContact(1, "email", new DefaultContactData("*****@*****.**"), true); ProfileContacts contacts = new ProfileContacts(Lists.newArrayList(contact)); when(loader.create(identity, contact)).thenReturn(Observable.just(Boolean.TRUE)); Observable<Result> result = service.create(identity, contacts); assertEquals(Result.success(), result.toBlocking().first()); }
@Test public void createFailsInternalUpdate() throws Exception { Identity identity = new Identity(UUID.randomUUID()); ProfileContact contact = new ProfileContact(1, "email", new DefaultContactData("*****@*****.**"), true); ProfileContacts contacts = new ProfileContacts(Lists.newArrayList(contact)); when(loader.create(identity, contact)).thenReturn(Observable.just(Boolean.FALSE)); Observable<Result> result = service.create(identity, contacts); assertEquals( Result.withServerCause("There was an unexpected error processing your request."), result.toBlocking().first()); }
@Test(timeout = 30000) public void testIssue1527() throws InterruptedException { // https://github.com/Netflix/RxJava/pull/1527 Observable<Integer> source = Observable.just(1, 2, 3, 4, 5, 6); Observable<Integer> reduced = source.reduce( new Func2<Integer, Integer, Integer>() { @Override public Integer call(Integer i1, Integer i2) { return i1 + i2; } }); Integer r = reduced.toBlocking().first(); assertEquals(21, r.intValue()); }
// validate payloads private void validate(EntityRef ref, ServicePayload servicePayload) throws Exception { Object obj_payloads = servicePayload.getProperty("payloads"); if (obj_payloads == null && ref == null) { throw new RequiredPropertyNotFoundException("notification", "payloads"); } if (obj_payloads != null) { if (!(obj_payloads instanceof Map)) { throw new IllegalArgumentException("payloads must be a JSON Map"); } final Map<String, Object> payloads = (Map<String, Object>) obj_payloads; final Map<Object, Notifier> notifierMap = getNotifierMap(payloads); Observable t = Observable.from(payloads.entrySet()) .subscribeOn(Schedulers.io()) .map( new Func1<Map.Entry<String, Object>, Object>() { @Override public Object call(Map.Entry<String, Object> entry) { String notifierId = entry.getKey(); Notifier notifier = notifierMap.get(notifierId); if (notifier == null) { throw new IllegalArgumentException( "notifier \"" + notifierId + "\" not found"); } ProviderAdapter providerAdapter = ProviderAdapterFactory.getProviderAdapter(notifier, em); Object payload = entry.getValue(); try { return providerAdapter.translatePayload(payload); // validate // specifically to // provider } catch (Exception e) { return e; } } }); Object e = t.toBlocking().lastOrDefault(null); if (e instanceof Throwable) { throw new Exception((Exception) e); } } }
@Test public void linesWritten() throws IOException { // given: final WritableResource<String, Void> resource = createDefaultResource(); final String expectedLine = createDefaultResourceState(); final int numLines = 3; // when: for (int i = 0; i < numLines; ++i) { final Observable<Void> response = resource.write(expectedLine); final Iterator<?> it = response.toBlocking().getIterator(); assertFalse(it.hasNext()); } // then: try (BufferedReader reader = new BufferedReader(new FileReader(this.file))) { for (int i = 0; i < numLines; ++i) { final String actualLine = reader.readLine(); assertEquals(expectedLine, actualLine); } assertNull(reader.readLine()); } }
/** * Retrieve and optionally display an image. See {@link #HtmlImage(String, boolean, int, boolean, * TextView)} for the various behaviours. * * @param url the URL to fetch from cache or network * @return a drawable containing the image, or <tt>null</tt> if <tt>onlySave</tt> is <tt>true</tt> */ @Nullable @Override public BitmapDrawable getDrawable(final String url) { if (cache.containsKey(url)) { return cache.get(url); } final Observable<BitmapDrawable> drawable = fetchDrawable(url); if (onlySave) { loading.onNext( drawable.map( new Func1<BitmapDrawable, String>() { @Override public String call(final BitmapDrawable bitmapDrawable) { return url; } })); cache.put(url, null); return null; } final BitmapDrawable result = view == null ? drawable.toBlocking().lastOrDefault(null) : getContainerDrawable(drawable); cache.put(url, result); return result; }
private JsonNode processEditEntityResponse( final String entityIdentifier, final Observable<Response> createEntityResponse, final String type) throws IOException { final Response response = createEntityResponse.toBlocking().firstOrDefault(null); if (response == null) { final String message = String.format("could not create new %s for '%s'", type, entityIdentifier); LOG.error(message); throw new WikidataImporterError(new WikidataImporterException(message)); } final int status = response.getStatus(); LOG.debug("response status = {}", status); if (status != 200) { final String message = String.format( "could not create new %s for '%s'; response status != 200 (was '%d').", type, entityIdentifier, status); LOG.error(message); throw new WikidataImporterError(new WikidataImporterException(message)); } final String responseBody = response.readEntity(String.class); LOG.debug("response body = {}", responseBody); final ObjectNode responseJSON = MAPPER.readValue(responseBody, ObjectNode.class); if (responseJSON == null) { final String message = String.format( "could not create new %s for '%s'; could not deserialize response.", type, entityIdentifier); LOG.error(message); throw new WikidataImporterError(new WikidataImporterException(message)); } final JsonNode errorNode = responseJSON.get(MEDIAWIKI_ERROR_IDENTIFIER); if (errorNode != null) { final String message = String.format( "could not create new %s for '%s'; an error occurred ('%s').", type, entityIdentifier, responseBody); LOG.debug(message); // return error so that it can be handled at the client return responseJSON; } final JsonNode successNode = responseJSON.get(MEDIAWIKI_SUCCESS_IDENTIFIER); if (successNode == null) { final String message = String.format( "could not create new %s for '%s'; no 'success' node in response ('%s')", type, entityIdentifier, responseBody); LOG.error(message); throw new WikidataImporterError(new WikidataImporterException(message)); } final int success = successNode.asInt(); if (success != 1) { final String message = String.format( "could not create new %s for '%s'; 'success' = '%d'", type, entityIdentifier, success); LOG.error(message); throw new WikidataImporterError(new WikidataImporterException(message)); } final JsonNode entityNode = responseJSON.get(MEDIAWIKI_ENTITY_IDENTIFIER); if (entityNode == null) { final String message = String.format( "could not create new %s for '%s'; no 'entity' node in response ('%s')", type, entityIdentifier, responseBody); LOG.error(message); throw new WikidataImporterError(new WikidataImporterException(message)); } return entityNode; }
/** * Over a period of several 'windows' a single attempt will be made and fail and then finally * succeed and close the circuit. * * <p>Ensure the circuit is kept open through the entire testing period and that only the single * attempt in each window is made. */ @Test public void testMultipleTimeWindowRetriesBeforeClosingCircuit() { String key = "cmd-H"; try { int sleepWindow = 200; HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); cmd1.execute(); HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key); cmd4.execute(); // everything has failed in the test window so we should return false now System.out.println("!!!! 1 4 failures, circuit will open on recalc"); Thread.sleep(100); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); // wait for sleepWindow to pass System.out.println("!!!! 2 Sleep window starting where all commands fail-fast"); Thread.sleep(sleepWindow + 50); System.out.println("!!!! 3 Sleep window over, should allow singleTest()"); // but the circuit should still be open assertTrue(cb.isOpen()); // we should now allow 1 request, and upon failure, should not affect the circuit breaker, // which should remain open HystrixCommand<Boolean> cmd5 = new FailureCommand(key, 60); Observable<Boolean> asyncResult5 = cmd5.observe(); System.out.println("!!!! Kicked off the single-test"); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); System.out.println("!!!! Confirmed that no other requests go out during single-test"); asyncResult5.toBlocking().single(); System.out.println("!!!! SingleTest just completed"); // all requests should still be blocked, because the singleTest failed assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); // wait for sleepWindow to pass System.out.println("!!!! 2nd sleep window START"); Thread.sleep(sleepWindow + 50); System.out.println("!!!! 2nd sleep window over"); // we should now allow 1 request, and upon failure, should not affect the circuit breaker, // which should remain open HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 60); Observable<Boolean> asyncResult6 = cmd6.observe(); System.out.println("2nd singleTest just kicked off"); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); System.out.println("confirmed that 2nd singletest only happened once"); asyncResult6.toBlocking().single(); System.out.println("2nd singleTest now over"); // all requests should still be blocked, because the singleTest failed assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); // wait for sleepWindow to pass Thread.sleep(sleepWindow + 50); // but the circuit should still be open assertTrue(cb.isOpen()); // we should now allow 1 request, and upon success, should cause the circuit to be closed HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 60); Observable<Boolean> asyncResult7 = cmd7.observe(); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); asyncResult7.toBlocking().single(); // all requests should be open again assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); // and the circuit should be closed again assertFalse(cb.isOpen()); // and the circuit should be closed again assertFalse(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }