Szoftverfejlesztés J2EE platformon - Labor: JMS

A VIK Wikiből

Ez az oldal a korábbi SCH wikiről lett áthozva.

Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!

Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.



JMS API: javax.jms.

  • ConnectionFactory
  • Connection
  • Session
  • Queue
Ezen a helyen volt linkelve a(z) JMS_handout.doc nevű fájl ("JMS_handout.doc" link szöveggel) a régi wiki http://wiki-old.sch.bme.hu/bin/view/Valaszthato/J2EELaborJMS oldaláról. (Ha szükséged lenne a fájlra, akkor a pontos oldalmegnevezéssel együtt küldd el a wiki@sch.bme.hu címre a kérésedet)
JMS segédlet

Sorok konfigurációja

Admin Console / Configuration / Java Message Service / Physical Destinations

  • New...; vicc_air_req: queue
  • New...; vicc_air_resp: queue
  • New...; vicc_air_dflight: topic

Resources / JMS Resources / Connection Factories

  • New...; JNDI Name: jms/ViccAirCFactory; Type: javax.jms.ConnectionFactory

Resources / JMS Resources / Destination Resources

  • New...; JNDI Name: jms/ViccAirRequest; Type: javax.jms.Queue; Name: vicc_air_req
  • New...; JNDI Name: jms/ViccAirResponse; Type: javax.jms.Queue; Name: vicc_air_resp
  • New...; JNDI Name: jms/ViccAirDFlight; Type: javax.jms.Topic; Name: vicc_air_dflight

Félkész projektek

Nyissuk meg a

Ezen a helyen volt linkelve a(z) viccair.zip nevű fájl ("Vicc_air" link szöveggel) a régi wiki http://wiki-old.sch.bme.hu/bin/view/Valaszthato/J2EELaborJMS oldaláról. (Ha szükséged lenne a fájlra, akkor a pontos oldalmegnevezéssel együtt küldd el a wiki@sch.bme.hu címre a kérésedet)
projektet, azon belul a Vicc_air-ejb / EnterpriseBean / TicketHandlerMDB beant.

Erdemes megnezni, hogy kellett EJB 2.1-ben Message Driven Bean-t hivni (sendJMSMessageToPartnerResponseDestination metodus) — ilyet nem kell csinalni EJB3-ban. :)

Nyissuk meg a

Ezen a helyen volt linkelve a(z) travel.zip nevű fájl ("Travel" link szöveggel) a régi wiki http://wiki-old.sch.bme.hu/bin/view/Valaszthato/J2EELaborJMS oldaláról. (Ha szükséged lenne a fájlra, akkor a pontos oldalmegnevezéssel együtt küldd el a wiki@sch.bme.hu címre a kérésedet)
projektet es oldjuk fel a referencia problemakat.

Travel / Java EE Modules-on belul nyissuk meg a Travel-ejb.jar-t es a Travel-war.war-t. Oldjuk fel a tovabbi referencia problemakat. A szukseges jar-ok a Travel es a displaytag konyvtarakban vannak.

A Travel-ejb-ben a TicketOrderBean tartalmazza az uzenetformatumot.

Session bean

Az OrderHandlerBean-t fogjuk kiegészíteni.

Erőforrás injektálás:

@PersistenceContext
private EntityManager em;

@Resource(mappedName="jms/ViccAirCFactory")
private ConnectionFactory cf;

@Resource(mappedName="jms/ViccAirRequest")
private Queue request;

Foglalás bejegyzése:

public void createNewOrder(Orders orderData) {
	 orderData.setStatus(0);
	 em.persist(orderData);
		  
	 Connection conn = null;
	 Session session = null;
	 try {
		  conn = cf.createConnection();
		  session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

		  MessageProducer producer = session.createProducer(request);

		  TicketOrderBean b = new TicketOrderBean();
		  b.setCustomername(orderData.getCustomername());
		  b.setDepart(orderData.getDepart());
		  b.setFlightId(orderData.getFlightId());
		  b.setOrderId(orderData.getOrderId());
		  b.setSeats(orderData.getSeats());
		  b.setStatus(orderData.getStatus());

		  Message message = session.createObjectMessage(b);
		  producer.send(message);
	 }
	 ...
}

Foglalások listázása:

public List<Orders> getOrders() {
	 return em.createQuery("SELECT o FROM Orders o").getResultList();
}

Foglalás státuszának módosítása:

public void updateOrderStatus(Integer orderId, Integer statusId) {
	 Orders o = em.find(Orders.class, orderId);
	 o.setStatus(statusId);
	 em.persist(o);
}

Deployoljuk a két alkalmazást. Ha nem találja a jdbc/sample-t:

  • Admin Console / Resources / JDBC / Connection Pools / New...
    • Name: SamplePool
    • DataSource Classname: org.apache.derby.jdbc.ClientDataSource
    • Resource Type: javax.sql.DataSource
    • ServerName: localhost
    • DatabaseName: sample
    • User: app
    • Password: app
    • PortNumber: 1527
  • Admin Console / Resources / JDBC / JDBC Resources / New...
    • JNDI Name: jdbc/sample
    • Pool Name: SamplePool

Futtatás: http://zone6:8080/Travel-war/

Message-driven bean a foglaláshoz

A foglaláshoz tartozó üzleti logika nagyon egyszerű:

  • 20 másodpercig várakozó állapotban van;
  • ha legfeljebb 10 ülést foglaltak, elfogadja;
  • különben elutasítja a ViccAir.

Travel-ejb / New... / Message Driven Bean

  • Name: PartnerResponse
  • Package: hu.bme.aait
  • Type: Queue
@MessageDriven(mappedName = "jms/ViccAirResponse", activationConfig =  {
	 @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
	 @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class PartnerResponse implements MessageListener {
	 
	 @EJB
	 OrderHandlerLocal order;
	 
	 /** Creates a new instance of PartnerResponse */
	 public PartnerResponse() {
	 }
	 
	 public void onMessage(Message message) {
		  System.out.println("Jott valasz: " + message);
		  if (message instanceof ObjectMessage) {
				try {
					 TicketOrderBean b = (TicketOrderBean) ((ObjectMessage)message).getObject();
					 System.out.println("OrderId: " + b.getOrderId() + " status: " + b.getStatus());
					 order.updateOrderStatus(b.getOrderId(), b.getStatus());
				} catch (Exception e) {
					 throw new RuntimeException(e);
				}
		  } else {
				System.out.println("Nem Objectmessage!" + message.getClass());
		  }
	 }
}

Tesztelés: http://zoneX:8080/Travel-war/

Message-driven bean a járat törléshez

A járat státuszának azonnal át kell íródnia töröltre (-2).

Travel-ejb / New... / Message Driven Bean

  • Name: DeletedFlights
  • Package: hu.bme.aait
  • Type: Topic
@MessageDriven(mappedName = "jms/ViccAirDFlights", activationConfig =  {
	 @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
	 @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
	 @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
	 @ActivationConfigProperty(propertyName = "clientId", propertyValue = "DeletedFlights"),
	 @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "DeletedFlights")
})
public class DeletedFlights implements MessageListener {
	 
	 @PersistenceContext
	 private EntityManager em;
	 
	 /** Creates a new instance of DeletedFlights */
	 public DeletedFlights() {
	 }
	 
	 public void onMessage(Message message) {
		  System.out.println("Jott torles uzenet: " + message);
		  if (message instanceof TextMessage) {
				try {
					 String id = ((TextMessage)message).getText();
					 
					 Query q = em.createNamedQuery("Orders.findByFlightId");
					 q.setParameter("flightId", id);
					 List<Orders> orders = q.getResultList();
						  
					 for (Orders o : orders) {
						  o.setStatus(-2);
						  em.persist(o);
						  System.out.println("Order frissitve: " + o.getOrderId());
					 }
				} catch (Exception e) {
					 throw new RuntimeException(e);
				}
		  }
	 }
}

Tesztelés: http://zoneX:8080/Vicc_air/

Ha az appszerver logban nem jelenik meg a "Jott torles uzenet: ..." sor, valamit elcsesztél a konfigurálásnál.

Extra: összetett EJB-QL lekérdezések

Az EJB-QL 3.0 támogatja a vetítést, és az aggregált függvényeket, a módosítást és a törlést. A lekérdezés objektum tömbbel tér vissza. Íme egy példa a használatra:

List l = em.createQuery("Select o.flightId, count(o.orderId) from Orders o group by o.flightId")
	 .getResultList();
for (Object o : l) {
	 Object[] oa = (Object[]) o;
	 System.out.print("Len: " + oa.length + " -");
	 for (Object f : oa)
		  System.out.print(" "+f);
	 System.out.println();
}

EJB-QL 3.0 QuickRef

-- Peti - 2006.11.22.