0

Ich teste ein Upgrade meiner Spring Cloud DataFlow-Dienste von Spring Cloud Dalston.SR4/Spring Boot 1.5.9 bis Spring Cloud Edgware/Spring Boot 1.5.9 . Einige meiner Dienste erweitern Source- (oder Sink-) Komponenten von App-Startern. Ich habe festgestellt, dass dies nicht mit Spring Cloud Edgware funktioniert.Überschriebene RabbitSourceConfiguration (App-Starter) funktioniert nicht mit Spring Cloud Edgware

Zum Beispiel habe ich org.springframework.cloud.stream.app.rabbit.source.RabbitSourceConfiguration überschrieben und meine App an meine überschriebene Version gebunden. Dies hat früher mit Spring Cloud-Versionen gearbeitet, die fast ein Jahr zurückreichen.

Mit Edgware, erhalte ich die folgende (ob die App eigenständig ausgeführt wird oder innerhalb Datenfluß):

*************************** 
APPLICATION FAILED TO START 
*************************** 

Description: 

Field channels in org.springframework.cloud.stream.app.rabbit.source.RabbitSourceConfiguration required a bean of type 'org.springframework.cloud.stream.messaging.Source' that could not be found. 


Action: 

Consider defining a bean of type 'org.springframework.cloud.stream.messaging.Source' in your configuration. 

ich das gleiche Verhalten mit dem 1.3.0.RELEASE und 1.2.0.RELEASE des Frühlings erhalten -cloud-starter-stream-kaninchen.

Ich überschreibe RabbitSourceConfiguration, damit ich einen Header-Mapper auf dem AmqpInboundChannelAdapter festlegen kann, und auch einen Verbindungstest vor dem Starten des Containers durchführen.

Meine Unterklasse ist an die Spring Boot-Anwendung mit @EnableBinding(HeaderMapperRabbitSourceConfiguration.class) gebunden. Eine cutdown Version meiner Unterklasse ist:

public class HeaderMapperRabbitSourceConfiguration extends RabbitSourceConfiguration { 

    public HeaderMapperRabbitSourceConfiguration(final MyHealthCheck healthCheck, 
               final MyAppConfig config) { 
     // ... 
    } 

    @Bean 
    @Override 
    public AmqpInboundChannelAdapter adapter() { 
     final AmqpInboundChannelAdapter adapter = super.adapter(); 
     adapter.setHeaderMapper(new NotificationHeaderMapper(config)); 

     return adapter; 
    } 

    @Bean 
    @Override 
    public SimpleMessageListenerContainer container() { 
     if (config.performConnectivityCheckOnStartup()) { 

      if (LOGGER.isInfoEnabled()) { 
       LOGGER.info("Attempting connectivity with ..."); 
      } 
      final Health health = healthCheck.health(); 
      if (health.getStatus() == Status.DOWN) { 
       LOGGER.error("Unable to connect ....."); 
       throw new UnableToLoginException("Unable to connect ..."); 
      } else if (LOGGER.isInfoEnabled()) { 
       LOGGER.info("Connectivity established with ..."); 
      } 
     } 

     return super.container(); 
    } 
} 
+0

Zeigen Sie Ihre 'RabbitSourceConfiguration'. –

+0

Ich habe die Config-Klasse zur ursprünglichen Frage hinzugefügt. – bikerlad

Antwort

0

Sie sollten nie wirklich wie healthCheck.health(); innerhalb einer @Bean Definition Sachen tun. Der Anwendungskontext ist noch nicht vollständig erstellt oder gestartet. Je nach der Reihenfolge, in der die Beans erstellt werden, funktioniert das möglicherweise oder auch nicht.

Wenn Sie verhindern möchten, dass die App startet, fügen Sie eine Bean hinzu, die SmartLifecycle implementiert, setzen Sie die Bean in eine späte Phase (hoher Wert), damit sie nach allem anderen gestartet wird. Dann setzen Sie Ihren Code in start(). autStartup muss wahr sein.

In diesem Fall wird es ausgeführt, bevor die Stream-Infrastruktur den Kanal erstellt hat.

Einige Bestellungen haben sich möglicherweise von der früheren Version geändert, aber in jedem Fall ist die Durchführung einer solchen Aktivität in einer @Bean Definition gefährlich.

Sie waren zufällig gerade glücklich.

EDIT

ich Ihre @EnableBinding nur bemerkt, ist falsch; Es sollte Source.class sein. Ich kann nicht sehen, wie das jemals funktioniert hätte - das ist, was die Bohne für das channels Feld des Typs Source erzeugt.

Dies funktioniert gut für mich nach dem 1.3.0.RELEASE Strom und das Bindemittel zu aktualisieren ...

@Configuration 
public class MySource extends RabbitSourceConfiguration { 

    @Bean 
    @Override 
    public AmqpInboundChannelAdapter adapter() { 
     AmqpInboundChannelAdapter adapter = super.adapter(); 
     adapter.setHeaderMapper(new MyMapper()); 
     return adapter; 
    } 


} 

und

@SpringBootApplication 
@EnableBinding(Source.class) 
public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 

} 

Wenn das nicht funktioniert, bearbeiten Sie bitte die Frage um dein POM zu zeigen.

+0

Ok, Punkt auf den Gesundheitscheck genommen, aber das beantwortet meine ursprüngliche Frage nicht.Ich kann ein leeres Override von RabbitSourceConfiguration haben und immer noch beklagt Edgware, keine Quelle gefunden zu haben. Tatsächlich habe ich andere ähnliche Fälle mit überschriebenen App-Startquellen und -senken (ohne Gesundheitschecks), die jetzt alle mit Edgware versagen. Der Gesundheitscheck ist ein Ablenkungsmanöver. – bikerlad

+0

Ihre '@ EnableBinding' ist falsch - siehe meine Bearbeitung. –

+0

Das funktioniert! Ich hatte versucht, die Hauptanwendungsklasse an Source.class zu binden, aber das hat nicht alleine funktioniert. Was funktioniert hat, ist dein Beispiel. Binden Sie die App-Klasse an Source.class * und *, markieren Sie die Unterklassen-Konfiguration als @Configuration. Danke für Ihre Hilfe. – bikerlad