2017-04-17 20 views
7

uczę przykład Wiosna Boot i JMS i tak, jestem dość nowy na tymJak migrować Wiosna Boot JMS z ActiveMQ Oracle Advanced Queuing

Ponieważ pracujemy z Oracle, chciałbym migrować przykład JMS z Spring Boot & z ActiveMQ do Oracle Advanced Queuing. Jednak naprawdę znajduję bardzo mało informacji na ten temat.

O ile widzę, muszę zastąpić poniższy kod dla wersji Oracle, ale nie udało mi się dowiedzieć, jak to zrobić.

@Bean 
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, 
               DefaultJmsListenerContainerFactoryConfigurer configurer) { 
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); 
    // This provides all boot's default to this factory, including the message converter 
    configurer.configure(factory, connectionFactory); 
    // You could still override some of Boot's default if necessary. 
    return factory; 

}

Kod pochodzenie można znaleźć na Github

pomoc będzie bardzo mile widziane!

+0

IMHO jest to zamierzone. Jeśli twój kod działa na WebLogic (który jest również produktem Oracle), konfiguracja jest dość łatwa (patrz http://danielveselka.blogspot.cz/2009/07/mdb-3-0-on-weblogic-103-using-oracle -aq.html). Obawiam się, że inne serwery aplikacji nie oferują JMS dla łączników AQ (adapterów zasobów). – ibre5041

+0

Nie, nie chcę się łączyć z WebLogic, ale bezpośrednio z Oracle Advanced Queuing (AQ). W moim programie bez Spring Boot używam: '\t \t \t qconFactory = AQjmsFactory.getQueueConnectionFactory (hostName, serviceName, port," thin "); \t \t \t qcon = qconFactory.createQueueConnection (nazwa użytkownika, hasło); \t \t \t qsession = qcon.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); \t \t \t queueTable = ((AQjmsSession) qsession) .getQueueTable (nazwa_użytkownika, nazwa_kolejki_tabeli); \t \t \t Kolejka = ((AQjmsSession) qsession) .getQueue (nazwa użytkownika, nazwaKolejki); ' – dhmc

+0

Co było próbą wyjaśnienia. Oracle AQ może działać jako standardowy dostawca JMS Java EE. Które może ułatwić twoje przejście z ActiveMQ. (W rzeczywistości nie byłoby żadnych zmian w kodzie źródłowym). Ale to może działać tylko w pewnych okolicznościach. – ibre5041

Odpowiedz

1

Poniższa konfiguracja rozwiąże Twoje pytania.

1 - Utwórz konfigurację. Dla tej odpowiedzi umieściłem wszystkie pliki konfiguracyjne w pliku aplikacji. Możesz umieścić je w oddzielnych klasach, co eliminuje obawy.

@SpringBootApplication 
@EnableJms 
public class Application { 
    private static Random rand = new Random(); 

    @Bean 
    DataSource dataSource() throws SQLException { 
     OracleDataSource dataSource = new OracleDataSource(); 
     dataSource.setUser("yourusername"); 
     dataSource.setPassword("yourpassword"); 
     dataSource.setURL("jdbc:oracle:thin:@yourserver:1521:xe"); 
     dataSource.setImplicitCachingEnabled(true); 
     dataSource.setFastConnectionFailoverEnabled(true); 
     return dataSource; 
    }  

    @Bean 
    public QueueConnectionFactory connectionFactory() throws Exception { 
     return AQjmsFactory.getQueueConnectionFactory(dataSource()); 
    } 

    @Bean 
    public JmsTemplate jmsTemplate() throws Exception { 
     JmsTemplate jmsTemplate = new JmsTemplate(); 
     jmsTemplate.setConnectionFactory(connectionFactory()); 
     jmsTemplate.setMessageConverter(jacksonJmsMessageConverter()); 
     return jmsTemplate; 
    } 

    @Bean 
    public JmsListenerContainerFactory<?> myJMSListenerFactory(QueueConnectionFactory connectionFactory,              DefaultJmsListenerContainerFactoryConfigurer configurer) { 
     DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); 
     // factory.setConcurrency("15-20"); 
     factory.setMessageConverter(jacksonJmsMessageConverter()); 
     configurer.configure(factory, connectionFactory); 
     return factory; 
    } 

    @Bean 
    public MessageConverter jacksonJmsMessageConverter() { 
     MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); 
     converter.setTargetType(MessageType.TEXT); 
     converter.setTypeIdPropertyName("_type"); 
     return converter; 
    } 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); 
     JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); 
     for (int i = 0; i < 10; i++) { 
      int waitSecs = rand.nextInt(3); 
      jmsTemplate.convertAndSend("YourQueueName", new Email("[email protected]", "Hello " + i, waitSecs)); 
     } 
    } 
} 

2 - Nakręć JMS słuchacz

@Component 
public class Receiver { 
    @JmsListener(destination = "YourQueueName", containerFactory = "myJMSListenerFactory") 
    public void receiveEmail(Email email) { 
     System.out.println("Received <" + email + ">"); 
    } 
} 

3 - Maven i Oracle

Możesz dodać oracle6 lub Oracle7 słoiki osobno do lib ścieżkę, jak pokazano na this post.

Reszta pliku Mavana jest dość standardowa.

<properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <java.version>1.8</java.version> 
    </properties> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.5.2.RELEASE</version> 
    </parent> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-activemq</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-databind</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
      </plugin> 
     </plugins> 
    </build> 

4 - działalności obiektów. Obiekty takie jak e-mail to domeny biznesowe POJO. Nie umieszczę ich tutaj.

@Testing, to działa jak uroku ;-)

1

Nie sądzę, że musisz zmienić metodę myFactory jako taką, zamiast tego musisz utworzyć connectionFactory, która łączy się z kolejką Oracle. Miałem podobną konfigurację, w dev użyłem artemis do uruchomienia mojego JUNIT-a i w prod wykorzystałem kolejkę oracle. Poniżej znajduje się klasa, którą zdefiniowałem, aby utworzyć connectionFactory.

import java.util.HashMap; 
import java.util.Map; 
import java.util.Properties; 

import javax.jms.ConnectionFactory; 
import javax.jms.Destination; 
import javax.naming.Context; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary; 
import org.springframework.jms.annotation.EnableJms; 
import org.springframework.jms.connection.CachingConnectionFactory; 
import org.springframework.jms.core.JmsTemplate; 
import org.springframework.jndi.JndiObjectFactoryBean; 
import org.springframework.jndi.JndiTemplate; 


/** 
* @author Karthik Prasad 
* @since 1.0.0.0 
*  <p> 
*  Configuration file for weblogic JMS connection 
*/ 
@Configuration 
@EnableJms 
@ConfigurationProperties(prefix = "spring.wls.jms") 
@ConditionalOnProperty(prefix = "spring.wls.jms", name = "url") 
public class WLSJmsConfiguration { 

    /** 
    * SJ4J Log instance 
    */ 
    private static final Logger LOG = LoggerFactory.getLogger(WLSJmsConfiguration.class); 

    /** 
    * provider url 
    */ 
    private String url; 
    /** 
    * username of weblogic server using which JNDI connection will be 
    * established 
    */ 
    private String username; 
    /** 
    * password of weblogic server using which JNDI connection will be 
    * established 
    */ 
    private String password; 
    /** 
    * JMS Connection factory name configured in weblogic server 
    */ 
    private String connectionFactoryName; 

    /** 
    * Name of destination queue 
    */ 
    private String targetQueue; 

    /** 
    * The Response Queue 
    */ 
    private String replyQueue; 


    /** 
    * URL to access weblogic Connectionfactory, property is set from properties 
    * file 
    * 
    * @see ConfigurationProperties 
    * @param password 
    *   weblogic url to JNDI 
    */ 
    public void setUrl(final String url) { 
     this.url = url; 
    } 

    /** 
    * username to access weblogic queue, property is set from properties file 
    * 
    * @see ConfigurationProperties 
    * @param username 
    *   weblogic username to access queue 
    */ 
    public void setUsername(final String username) { 
     this.username = username; 
    } 

    /** 
    * Password to access weblogic queue, property is set from properties file 
    * 
    * @see ConfigurationProperties 
    * @param password 
    *   weblogic password to access queue 
    */ 
    public void setPassword(final String password) { 
     this.password = password; 
    } 

    /** 
    * Setter of connection factory name, property is set from properties file 
    * 
    * @see ConfigurationProperties 
    * @param connectionFactoryName 
    *   ConnectionFactory from properties file 
    */ 
    public void setConnectionFactoryName(final String connectionFactoryName) { 
     this.connectionFactoryName = connectionFactoryName; 
    } 

    /** 
    * Setter for {@link #targetQueue} 
    * 
    * @param targetQueue 
    *   the targetQueue to set 
    */ 
    public void setTargetQueue(final String targetQueue) { 
     this.targetQueue = targetQueue; 
    } 

    /** 
    * @param replyQueue 
    *   the replyQueue to set 
    */ 
    public void setReplyQueue(final String replyQueue) { 
     this.replyQueue = replyQueue; 
    } 


    /** 
    * Get JNDI properties from properties file 
    * 
    * @return list of Weblogic jndi properties 
    */ 
    private Properties getJNDiProperties() { 

     final Properties jndiProps = new Properties(); 
     LOG.debug("Initializing JndiTemplate"); 
     LOG.debug("Url is {}", url); 
     jndiProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); 
     jndiProps.setProperty(Context.PROVIDER_URL, url); 
     if (username != null && !username.isEmpty()) { 
      jndiProps.setProperty(Context.SECURITY_PRINCIPAL, username); 
     } 
     if (password != null && !password.isEmpty()) { 
      jndiProps.setProperty(Context.SECURITY_CREDENTIALS, password); 
     } 
     return jndiProps; 

    } 

    /** 
    * Create JndiTemplate for target weblogic server from provided JNDI 
    * properties 
    * 
    * @return Bean of Jndi Template 
    */ 
    @Bean 
    public JndiTemplate jndiTemplate() { 
     final JndiTemplate jndiTemplate = new JndiTemplate(); 
     jndiTemplate.setEnvironment(getJNDiProperties()); 
     return jndiTemplate; 
    } 

    /** 
    * Creates instance of Jndi Object Factory bean from Jndi Template 
    * 
    * @param jndiTemplate 
    *   Jndi Template for weblogic server 
    * @return Bean of JndiObject Factory 
    */ 
    @Bean(name = "jmsJndiConnectionFactory") 
    public JndiObjectFactoryBean jndiObjectFactoryBean(final JndiTemplate jndiTemplate) { 

     final JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean(); 
     LOG.debug("Creating Weblogic JMS connection factory"); 
     jndiObjectFactoryBean.setJndiTemplate(jndiTemplate); 
     // connectionFactory name. 
     LOG.debug("ConnectoinFactory Name is {}", connectionFactoryName); 
     jndiObjectFactoryBean.setJndiName(connectionFactoryName); 
     return jndiObjectFactoryBean; 

    } 

    /** 
    * Create Jms Connection factory from Jndi Objectfactory 
    * 
    * @param jndiObjectFactoryBean 
    *   Jndi Object factory bean 
    * @return Returns Jms Connection factory Bean 
    */ 
    @Bean(name = "jmsWlsConnectionFactory") 
    public ConnectionFactory jmsConnectionFactory(final JndiObjectFactoryBean jndiObjectFactoryBean) { 
     final ConnectionFactory connectionFactory = (ConnectionFactory) jndiObjectFactoryBean.getObject(); 
     LOG.debug("ConnectoinFactory is null? {}", connectionFactory == null); 
     return connectionFactory; 
    } 

    /** 
    * Wrap Weblogic Connection Factory around caching factory 
    * 
    * @return 
    */ 
    @Bean(name = "jmsConnectionFactory") 
    @Primary 
    public ConnectionFactory connectionFactoryProxy() { 
     final CachingConnectionFactory jmsConnectionFactory = new CachingConnectionFactory(
       (ConnectionFactory) appContext.getBean("jmsWlsConnectionFactory")); 
     jmsConnectionFactory.setCacheProducers(true); 
     jmsConnectionFactory.setSessionCacheSize(20); 
     return jmsConnectionFactory; 
    } 

    /** 
    * The instance of Target Queue retrieved from JNDI, this bean is created in 
    * dev profile, where one want to run the project in standalone mode but 
    * want to connect to Weblogic Server 
    * 
    * @return Bean of target queue instance 
    */ 
    @Bean 
    public Destination jmsQueueName() { 

     final JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean(); 
     jndiObjectFactoryBean.setJndiTemplate(jndiTemplate()); 
     jndiObjectFactoryBean.setJndiName(targetQueue); // queue name 
     return (Destination) jndiObjectFactoryBean.getObject(); 
    } 

    /** 
    * Create DestinationResolver to resolve QueueName 
    * 
    * @return Instance of JNDI Destination Resolver 
    */ 
    private DestinationResolver destinationResolver() { 
     final JMSDestinationResolver destinationResolver = new JMSDestinationResolver(); 
     final JndiHelper jndiHelper = new JndiHelper(getJNDiProperties()); 
     destinationResolver.setJndiTemplate(jndiHelper); 
     return destinationResolver; 
    } 

} 

The application.properties.

spring.wls.jms.url=t3://server01:8001,server02:8003 
spring.wls.jms.username=weblogic 
spring.wls.jms.password=password 
spring.wls.jms.connectionFactoryName=connectionFactory Name 
spring.wls.jms.targetQueue=queue_name 
spring.wls.jms.replyQueue=queue_name 

A trzeba dodać wlthint3client na ścieżce klas. Dostałem słoik od <weblogic_home>\wlserver\server\lib i stworzyłem zależność maven od słoika i pchnąłem do mojego lokalnego repo i dodałem jar jako zależność.

<dependency> 
     <groupId>com.oracle.weblogic</groupId> 
     <artifactId>wlthint3client</artifactId> 
     <version>12.2.1</version> 
     <scope>provided</scope> <!-- comment out this if you are deploying on tomcat or running the application standalone --> 
    </dependency> 
+0

Dzięki za odpowiedź. Idealny dla wszystkich korzystających z WebLogic. Jak jednak połączyć się z Oracle Advanced Queuing (AQ) BEZ POTRZEBY WEBLOGIC. Co to jest odpowiednik kodu ActiveMQ Spring Boot Oracle w przykładzie Pierwsze kroki z JMS, zobacz [Spring Boot Getting Start JMS] [1] Lub przykład [spring-boot-sample-activemq na Github] [ 2] [1]: https://spring.io/guides/gs/messaging-jms/ [2]: https://github.com/spring-projects/spring-boot/tree/master/spring -boot-samples/spring-boot-sample-activemq – dhmc

Powiązane problemy