2015-05-06 16 views
5

ich verwende Reaktor 2 und Spring 4. Hier ist der typische Code, den ich habe - ein Consumer mit einem Repository arbeitenHandhabung Ausnahmen von Reactor Spring

@Consumer 
public class ApplicationService { 

    @Selector(value="/applications/id", type = SelectorType.URI) 
    @ReplyTo 
    public Application byApplicationId(String id) throws ApplicationNotFoundException { 
     Application app = appRepo.findOne(id); 
     if(app == null) 
     throw new ApplicationNotFoundException("Application `" + id + "` could not be found."); 
     return app; 
    } 
} 

Dann habe ich einen Controller, der die Anfrage an einen eventBus gibt in denen gebe ich Anfragen und Rück eine Ausnahme Promise s Wert nicht gesetzt ein Promise

@RestController 
@RequestMapping("/applications") 
public class ApplicationsController { 
    @RequestMapping(value = "/{id}", method = GET, produces = APPLICATION_JSON_VALUE) 
    public Promise<Event<Application>> byApplicationId(@PathVariable final String id) { 
     final Promise<Event<Application>> p = Promises.prepare(env); 
     eventBus.sendAndReceive("/applications/id", Event.wrap(id), p); 
     return p; 
    } 

} 

Dinge funktionieren, aber im Fall von ApplicationService werfen, aber ich in th folgenden erhalte e-Konsole:

16:46:58.003 [main] ERROR reactor.bus.EventBus - null 
java.lang.reflect.UndeclaredThrowableException 
    at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:302) 
... 
Caused by: com.metlife.harmony.exceptions.ApplicationNotFoundException: Application `2860c555-0bc4-45e6-95ea-f724ae3f4464` could not be found. 
    at com.metlife.harmony.services.ApplicationService.byApplicationId(ApplicationService.java:46) ~[classes/:?] 
... 
Caused by: reactor.core.support.Exceptions$ValueCause: Exception while signaling value: reactor.bus.Event.class : Event{id=null, headers={}, [email protected], key=/applications/id, data=2860c555-0bc4-45e6-95ea-f724ae3f4464} 

Fragen sind:

  1. verwende ich Reactor und eventBus in die falsche Richtung? und wenn ja, was ist der richtige Weg

  2. vielleicht diese Funktionalität noch nicht implementiert ist

+0

'eventBus.sendAndReceive ("/ Anwendungen/id", Event.wrap (id), p) zur Verfügung,' es cuase nicht Fehler Gießen? –

+0

@AnadiMisra an welchem ​​Punkt? – EvgeniySharapov

+0

Ich habe versucht, Ihren Code aus Neugier und ich habe diese 'Die Methode sendAndReceive (Objekt, Ereignis , Consumer ) im Typ EventBus ist nicht anwendbar für die Argumente (String, Event , Promise >)' bei Linie, mein Promise-Objekt 'Versprechen > Antwort = Promises.prepare (env);' –

Antwort

3

Ich glaube, ich neu bewertet, die Strategie der Verwendung von Reactor in meiner Frühlings-Anwendung.

Nun mein Controller sieht aus wie

@RestController 
public class GreetingController { 

    @Autowired 
    private GreetingService greetingService; 

    @RequestMapping("/greeting") 
    public Promise<ResponseEntity<?>> greeting(final @RequestParam(value = "name", defaultValue = "World") String name) { 
     return greetingService.provideGreetingFor(name).map(new Function<Greeting, ResponseEntity<?>>() { 
      @Override 
      public ResponseEntity<?> apply(Greeting t) { 
       return new ResponseEntity<>(t, HttpStatus.OK); 
      } 
     }).onErrorReturn(WrongNameException.class, new Function<WrongNameException, ResponseEntity<?>>() { 
      @Override 
      public ResponseEntity<?> apply(WrongNameException t) { 
       return new ResponseEntity<>(t.getMessage(), HttpStatus.BAD_REQUEST); 
      } 
     }).next(); 
    } 
} 

Und der Service sieht aus wie

@Service 
public class GreetingService { 
    @Autowired 
    private Environment env; 

    private static final String template = "Hello, %s!"; 
    private final AtomicLong counter = new AtomicLong(); 

    public Stream<Greeting> provideGreetingFor(String name) { 
     return Streams.just(name).dispatchOn(env).map(new Function<String, Greeting>() { 
      @Override 
      public Greeting apply(String t) { 
       if (t == null || t.matches(".*\\d+.*")) 
        throw new WrongNameException(); 
       return new Greeting(counter.incrementAndGet(), String.format(template, t)); 
      } 
     }); 
    } 
} 

Was schlecht ist, ist, dass ich jetzt Stream<T> als Ergebnis des Verfahrens in dem Dienst verwenden (was Angeblich eine Geschäftslogik), so dass jeder, der den Dienst nutzt, sich nun der Art des Dienstes bewusst ist und als Ergebnis Stream in andere Teile des Codes, z Jetzt muss ich möglicherweise await() in dem Code verwenden, der den Dienst verwendet.

Voll Anwendung ist bei https://github.com/evgeniysharapov/spring-reactor-demo