+ All Categories
Home > Documents > Java Messaging Services

Java Messaging Services

Date post: 21-Jan-2016
Category:
Upload: ziya
View: 54 times
Download: 0 times
Share this document with a friend
Description:
Java Messaging Services. Presentation By Anurudh Gupta. Agenda. Introduction What is Messaging History Problems Messaging solves JMS API Architecture JMS API Programming Model JMS XML Pairing JMS with J2EE Limitations Sample Demo. Messaging - PowerPoint PPT Presentation
50
Java Java Messaging Messaging Services Services Presentation Presentation By By Anurudh Gupta Anurudh Gupta
Transcript
Page 1: Java  Messaging Services

Java Java Messaging Messaging ServicesServices

Presentation Presentation

ByBy

Anurudh GuptaAnurudh Gupta

Page 2: Java  Messaging Services

AgendaAgendaIntroductionIntroductionWhat is MessagingWhat is MessagingHistoryHistoryProblems Messaging solvesProblems Messaging solvesJMS API ArchitectureJMS API ArchitectureJMS API Programming ModelJMS API Programming ModelJMS XML PairingJMS XML PairingJMS with J2EEJMS with J2EELimitationsLimitationsSample DemoSample Demo

Page 3: Java  Messaging Services

MessagingMessaging Messaging means that programs communicate with each other Messaging means that programs communicate with each other

by sending data in message and not calling each other directlyby sending data in message and not calling each other directly MMessaging middlewareessaging middleware It isIt is aa software that allows two entities to communicate by software that allows two entities to communicate by

sending and receivingsending and receiving messages. In the same way that today’s messages. In the same way that today’s e-mail systems allow communication between two or more e-mail systems allow communication between two or more people,people,

MMessaging allows communication among two or more essaging allows communication among two or more applications, without requiring human intervention. Theseapplications, without requiring human intervention. These applications can reside independently on a wide variety of applications can reside independently on a wide variety of hardware devices.hardware devices.

Page 4: Java  Messaging Services

One of the most fundamental aspects of messaging One of the most fundamental aspects of messaging is its is its asynchronous natureasynchronous nature - the sender of the - the sender of the message does notmessage does not have to wait for the recipient to have to wait for the recipient to receive the information.receive the information.

Page 5: Java  Messaging Services

HistoryHistory

Messaging technologies have been with us since the Messaging technologies have been with us since the 1970s when they were used primarily to facilitate1970s when they were used primarily to facilitate communication among back-office mainframe communication among back-office mainframe applications running on dedicated network applications running on dedicated network connections. connections.

TheThe messaging paradigm has become popular again messaging paradigm has become popular again due to changing business practices and technological due to changing business practices and technological advancesadvances such as the widespread acceptance of the such as the widespread acceptance of the Internet Internet ,, and the and the proliferation of mobile networked proliferation of mobile networked devices such as laptop PCs, handheld digital devices such as laptop PCs, handheld digital assistants, and other web-enabledassistants, and other web-enabled input devices.input devices.

Page 6: Java  Messaging Services

What problems does messaging solve?What problems does messaging solve?

Disparate system integrationDisparate system integration Exchanging information with business partnersExchanging information with business partners Automating common business functionsAutomating common business functions Challenges of building next generation Challenges of building next generation

applicationsapplications

Page 7: Java  Messaging Services

2.check business rules

1.Price discount

Manufacture Retail OutletWare house Inventory

Messaging to automate business functionsMessaging to automate business functions

3. Check Inventory

4.Place Order

Page 8: Java  Messaging Services

Challenges of building next generation Challenges of building next generation applicationsapplications

Automotive e-marketplace

AutomobileManufacturer

A

Parts Supplier X

Parts Supplier W

Parts Supplier Y

Parts Supplier Z

AutomobileManufacturer

B

Page 9: Java  Messaging Services

Global Business transactionsGlobal Business transactions

Americas Brazil

Canada

USA

Asia/Pac

KoreaIndia

China

Europe

France Germany

UK

Page 10: Java  Messaging Services

Messaging is not the only wayMessaging is not the only way

RPC –based mechanismRPC –based mechanism CORBACORBA JAVA RMIJAVA RMI MICROSOFT DCOMMICROSOFT DCOM

Page 11: Java  Messaging Services

Application Client

Application ClientApplication Client

Application Client Application Client

Tightly Coupled RPC Based Architecture

Application Client

?

Page 12: Java  Messaging Services

Message Server Application Client

Application ClientApplication Client

Application Client

Application Client

Loosely Coupled Messaging Based Architecture

Page 13: Java  Messaging Services

Java Messaging ServiceJava Messaging Service The Java Message Service is a Java API that allows applications The Java Message Service is a Java API that allows applications

to create, send,receive, and read messages. to create, send,receive, and read messages. Designed by Sun and several partner companies, theDesigned by Sun and several partner companies, the JMS API JMS API

defines a common set of interfaces and associated semantics that defines a common set of interfaces and associated semantics that allowallow programs written in the Java programming language to programs written in the Java programming language to communicate with othercommunicate with other messaging messaging iiimplementations.implementations.

The JMS API minimizes the set of concepts a programmer must The JMS API minimizes the set of concepts a programmer must learn to uselearn to use messaging products, but provides enough features to messaging products, but provides enough features to support sophisticated messagingsupport sophisticated messaging applications. It strives to applications. It strives to maximize the portabilitymaximize the portability of JMS of JMS aapplicationspplications across JMS across JMS providers in the same messaging domain.providers in the same messaging domain.

The JMS Specification was first published in August 1998. The The JMS Specification was first published in August 1998. The latest versionlatest version of the JMS Specification is Version 1.0.2bof the JMS Specification is Version 1.0.2b

Page 14: Java  Messaging Services

Key JMS featuresKey JMS features

Flexible programming modelFlexible programming model Publish/SubscribePublish/Subscribe Point –To- PointPoint –To- Point ResilienceResilience Flexible event- based mechanismsFlexible event- based mechanisms Transaction supportTransaction support Subject-based routingSubject-based routing

Page 15: Java  Messaging Services

JMS API ArchitectureJMS API Architecture

A JMS application is composed of the following parts:A JMS application is composed of the following parts: AA JMS providerJMS provider is a messaging system that implements is a messaging system that implements

the JMS interfaces andthe JMS interfaces and provides administrative and control provides administrative and control features. An implementation of the J2EEfeatures. An implementation of the J2EE platform at platform at release 1.3 and above includes a JMS provider.release 1.3 and above includes a JMS provider.

JMS clientsJMS clients are the programs or components written in are the programs or components written in the Java programmingthe Java programming language that produce and consume language that produce and consume messages.messages.

MessagesMessages are the objects that communicate information are the objects that communicate information between JMS clients.between JMS clients.

Page 16: Java  Messaging Services

Administered objectsAdministered objects are preconfigured JMS objects are preconfigured JMS objects created by an administratorfor the use of clients. created by an administratorfor the use of clients.

There are two kinds of administered objectsThere are two kinds of administered objects DDestinations estinations CConnection factoriesonnection factories Native clientsNative clients are programs that use a messaging product’s are programs that use a messaging product’s

native client APInative client API instead of the JMS API. If the application instead of the JMS API. If the application was originally created before thewas originally created before the JMS API became JMS API became available, it is likely to include both JMS and native available, it is likely to include both JMS and native clients.clients.

Page 17: Java  Messaging Services

Messaging DomainsMessaging Domains

Point-to-Point Messaging DomainPoint-to-Point Messaging Domain

A point-to-point (PTP) product or application is built A point-to-point (PTP) product or application is built around the concept of messagearound the concept of message queues, senders, and queues, senders, and receivers.receivers.

Each message is addressed to a specific queue, andEach message is addressed to a specific queue, and receiving clients extract messages from the queue(s) receiving clients extract messages from the queue(s) established to hold their mes-sages.established to hold their mes-sages.

Page 18: Java  Messaging Services

Sender Queue

PotentialReceiver

PotentialReceiver

Point-to-Point MessagingPoint-to-Point Messaging

Message Broker

Page 19: Java  Messaging Services

PTP messaging has the following PTP messaging has the following ccharacteristicsharacteristics

Each message has only one consumer.Each message has only one consumer. There are no timing dependencies between a sender and a There are no timing dependencies between a sender and a

receiver of a message.receiver of a message. The receiver can fetch the message whether or not it was The receiver can fetch the message whether or not it was

running whenrunning when the client sent the message.the client sent the message. The receiver acknowledges the successful processing of a The receiver acknowledges the successful processing of a

message.message.

Page 20: Java  Messaging Services

Publish/Subscribe Messaging DomainPublish/Subscribe Messaging Domain

In a publish/subscribe (pub/sub) product or In a publish/subscribe (pub/sub) product or application, clients address messages toapplication, clients address messages to a topic. a topic. Publishers and subscribers are generally anonymous Publishers and subscribers are generally anonymous and may dynamicallyand may dynamically publish or subscribe to the publish or subscribe to the content hierarchy. content hierarchy.

The system takes care of distributingThe system takes care of distributing the messages the messages arriving from a topic’s multiple publishers to its arriving from a topic’s multiple publishers to its multiple subscribersmultiple subscribers..

Page 21: Java  Messaging Services

Publisher Topic

Subscriber

Subscriber

PPublish /Subscribe ublish /Subscribe MessagingMessaging

Message Broker

Page 22: Java  Messaging Services

Pub/Pub/SSub messaging has the following characteristicsub messaging has the following characteristics

Each message may have multiple consumers.Each message may have multiple consumers. There is a timing dependency between publishers There is a timing dependency between publishers

and subscribers, because aand subscribers, because a client that subscribes to client that subscribes to a topic can consume only messages published a topic can consume only messages published after theafter the client has created a subscription, and the client has created a subscription, and the subscriber must continue to be activesubscriber must continue to be active in order for in order for it to consume messages.it to consume messages.

Page 23: Java  Messaging Services

The JMS API relaxes this timing dependency to The JMS API relaxes this timing dependency to some extent by allowingsome extent by allowing clients to create clients to create durable durable subscriptionsubscriptionss. .

Durable subscriptions can receive messagesDurable subscriptions can receive messages sent sent while the subscribers are not active.while the subscribers are not active.

Durable subscriptions provide theDurable subscriptions provide the flexibility and flexibility and reliability of queues but still allow clients to send reliability of queues but still allow clients to send messages to manymessages to many recipients.recipients.

Page 24: Java  Messaging Services

Message ConsumptionMessage Consumption

Messaging products are inherently asynchronous Messaging products are inherently asynchronous in that there is no fundamentalin that there is no fundamental timing dependency timing dependency between the production and consumption of a between the production and consumption of a message. However, the JMS Specification uses message. However, the JMS Specification uses this term in a more precise sensethis term in a more precise sense

Page 25: Java  Messaging Services

Messages can beMessages can be consumed in either of two ways:consumed in either of two ways: SynchronouslSynchronouslyy:: A A subscriber or a receiver explicitly subscriber or a receiver explicitly

fetches the message fromfetches the message from the destination by calling the the destination by calling the receive receive method. The method. The receive receive method can blockmethod can block until a until a message arrives, or it can time out if a message does not message arrives, or it can time out if a message does not arrive within aarrive within a specified time limit.specified time limit.

AsynchronouslAsynchronouslyy:: A client can register a A client can register a message listener message listener with a consumer. Awith a consumer. A message listener is similar to an event message listener is similar to an event listener. Whenever a message arrives atlistener. Whenever a message arrives at the destination, the the destination, the JMS provider delivers the message by calling the listener’sJMS provider delivers the message by calling the listener’s

onMessage onMessage method, which acts on the contents of the method, which acts on the contents of the message.message.

Page 26: Java  Messaging Services

The JMS API ProgrammingThe JMS API Programming Model Model

THE basic building blocks of a JMS application areTHE basic building blocks of a JMS application are Administered objectsAdministered objects ( (CConnection factories and onnection factories and

DDestinations)estinations) ConnectionsConnections SessionsSessions Message producersMessage producers Message consumersMessage consumers MessagesMessages

Page 27: Java  Messaging Services

Connection Factory

Connection

SessionMessage

ConsumerMessageProducer

MessageDestination Destination

Creates

Creates

Creates Creates

CreatesReceives

FromSends to

Page 28: Java  Messaging Services

Connection FactoriesConnection Factories A A CConnection factoryonnection factory is the object a client uses to create is the object a client uses to create

a connection with a provider.a connection with a provider. A connection factory encapsulates a set of connection A connection factory encapsulates a set of connection

configuration parametersconfiguration parameters that has been defined by an that has been defined by an administrator.administrator.

Context ctx = new InitialContext();Context ctx = new InitialContext();QueueConnectionFactory QueueConnectionFactory

queueConnectionFactory =queueConnectionFactory =(QueueConnectionFactory) (QueueConnectionFactory)

ctx.lookup(“QueueConnectionFactory”);ctx.lookup(“QueueConnectionFactory”);

Page 29: Java  Messaging Services

DestinationsDestinations A A destination destination is the object a client uses to specify the is the object a client uses to specify the

target of messages it producestarget of messages it produces and the source of and the source of messages it consumes.messages it consumes.

In the PTP messaging domain, destinations are called In the PTP messaging domain, destinations are called queuesqueues

In the pub/sub messaging domain, destinations are In the pub/sub messaging domain, destinations are called called topics,topics,

Page 30: Java  Messaging Services

ConnectionsConnections A A connection connection encapsulates a virtual connection with a encapsulates a virtual connection with a

JMS provider. It could representJMS provider. It could represent an open TCP/IP an open TCP/IP socket between a client and a provider service daemon. socket between a client and a provider service daemon. We We use a connection to create one or more sessions.use a connection to create one or more sessions.

Like connection factories, connections come in two Like connection factories, connections come in two forms: they implementforms: they implement either the either the QueueConnectionQueueConnection or the or the TopicConnection TopicConnection interface.interface.

Page 31: Java  Messaging Services

SessionsSessions A A session session is a single-threaded context for producing and is a single-threaded context for producing and

consuming messages. consuming messages. We We use sessions to create message use sessions to create message producers, message consumers, and messages.producers, message consumers, and messages.

Sessions serialize the execution of message listeners;Sessions serialize the execution of message listeners;

Public javax .jms.[ToPublic javax .jms.[Topicpic/Queue]/Queue]

Session Session createSession(createSession(boolean boolean transacted,int acknowledgeMode)transacted,int acknowledgeMode)

Page 32: Java  Messaging Services

Session.AUTO_ACKNOWLEDGSession.AUTO_ACKNOWLEDGEE: The session automatically : The session automatically acknowledges a client’sacknowledges a client’s receipt of a message either when the client has receipt of a message either when the client has successfully returned fromsuccessfully returned from a call to a call to receive receive or when the or when the MessageListener MessageListener it has called to process the mes-sageit has called to process the mes-sage returns returns successfully.successfully.

Session.CLIENT_ACKNOWLEDGSession.CLIENT_ACKNOWLEDGEE: A client acknowledges a message : A client acknowledges a message by callingby calling the message’s the message’s acknowledge acknowledge method. In this mode, method. In this mode, acknowledgment takesacknowledgment takes place on the session level: acknowledging a place on the session level: acknowledging a consumed message automaticallyconsumed message automatically acknowledges the receipt of all messages acknowledges the receipt of all messages that have been consumed by its session.that have been consumed by its session.

Session.DUPS_OK_ACKNOWLEDGSession.DUPS_OK_ACKNOWLEDGE:E: This option instructs the session This option instructs the session to lazily acknowledgeto lazily acknowledge the delivery of messages. This is likely to result in the the delivery of messages. This is likely to result in the delivery ofdelivery of some duplicate messages if the JMS provider fails, so it should some duplicate messages if the JMS provider fails, so it should only be usedonly be used by consumers that can tolerate duplicate messages.by consumers that can tolerate duplicate messages.

Page 33: Java  Messaging Services

Message ProducersMessage Producers A A message producermessage producer is an object created by a session is an object created by a session

that is used for sending messagesthat is used for sending messages to a destination.to a destination.

The PTP form of a message producer implements the The PTP form of a message producer implements the QueueSenderQueueSender interface.interface.

The pub/sub form implements the The pub/sub form implements the TopicPublisher TopicPublisher interface.interface.

queueSender.send(message);queueSender.send(message);

topicPublisher.publish(message);topicPublisher.publish(message);

Page 34: Java  Messaging Services

Message ConsumersMessage Consumers A A message consumermessage consumer is an object created by a session that is an object created by a session that

is used for receiving messagesis used for receiving messages sent to a destinationsent to a destination A message consumer allows a JMS client to register A message consumer allows a JMS client to register

interest in a destinationinterest in a destination with a JMS provider. The JMS with a JMS provider. The JMS provider manages the delivery of messages from aprovider manages the delivery of messages from a

destination to the registered consumers of the destination.destination to the registered consumers of the destination. The PTP form of message consumer implements the The PTP form of message consumer implements the

QueueReceiver QueueReceiver interface.interface. The pub/sub form implements theThe pub/sub form implements the TopicSubscriber TopicSubscriber

interface.interface.

Page 35: Java  Messaging Services

Message ListenersMessage Listeners A A message listenermessage listener is an object that acts as an is an object that acts as an

asynchronous event handler for messages.asynchronous event handler for messages.

It implements the It implements the MessageListenerMessageListener interface, which contains one interface, which contains one method,method,onMessagonMessage.In the.In thee onMessage onMessage method, method, wewe define the actions to be taken when define the actions to be taken when amessage arrives.amessage arrives.

Page 36: Java  Messaging Services

Message SelectorsMessage Selectors

If our messaging application needs to filter the If our messaging application needs to filter the messages it receives, messages it receives, wewe can use a can use a JMS API JMS API message selectormessage selector, which allows a message , which allows a message consumer to specify the messagesconsumer to specify the messages it is it is interested in.interested in.

Message selectors assign the work of filtering Message selectors assign the work of filtering messages tomessages to the JMS provider rather than the the JMS provider rather than the application.application.

Page 37: Java  Messaging Services

MessagesMessages AA JMS message has three parts, which are JMS message has three parts, which are HHeadereader A JMS message header contains a number of predefined fields, A JMS message header contains a number of predefined fields,

which containwhich contain values that both clients and providers use to values that both clients and providers use to identify and route messages.identify and route messages.

Properties Properties (optional)(optional) You can create and set properties for messages if you need values You can create and set properties for messages if you need values

in addition toin addition to those provided by the header fields. You can use those provided by the header fields. You can use properties to provide compatibilityproperties to provide compatibility with other messaging systems, with other messaging systems, or you can use them to create message selectorsor you can use them to create message selectors

Page 38: Java  Messaging Services

A bodyA body (optional) (optional)

The JMS API defines five different message body formats, The JMS API defines five different message body formats, also called messagealso called message types, which allow you to send and types, which allow you to send and receive data in many different forms, and whichreceive data in many different forms, and which provide provide compatibility with existing messaging formats.compatibility with existing messaging formats.

Page 39: Java  Messaging Services

Message Type Body ContainsMessage Type Body Contains TextMessage TextMessage A A java.lang.String java.lang.String object (for example, the contents object (for example, the contents

of an eXtended Markup Language file)of an eXtended Markup Language file) MapMessage MapMessage A set of name-value pairs, where names are A set of name-value pairs, where names are String String

objects, and values are primitive types in the Java programming language.objects, and values are primitive types in the Java programming language. BytesMessageBytesMessage A stream of uninterpreted bytes. This message type is A stream of uninterpreted bytes. This message type is

for literally encoding a body to match an existing message format.for literally encoding a body to match an existing message format. StreamMessageStreamMessage A stream of primitive values in the Java A stream of primitive values in the Java

programming language.It is filled and read sequentially.programming language.It is filled and read sequentially. ObjectMessageObjectMessage A Serializable object in the Java programming A Serializable object in the Java programming

languagelanguage Message Message Composed of header fields and properties only. This Composed of header fields and properties only. This message type is useful when a message body is not required.message type is useful when a message body is not required.

Page 40: Java  Messaging Services

Message PersistenceMessage Persistence

A A persistent messagepersistent message is guaranteed to be delivered at least is guaranteed to be delivered at least onceonce-it is -it is not considered sent until it has been safely written in the file or not considered sent until it has been safely written in the file or database. database.

Non-persistent messagesNon-persistent messages are are not stored.not stored. They are guaranteed to be They are guaranteed to be delivered at least delivered at least onceonce unless there is a system failure, in which case unless there is a system failure, in which case messages may be lostmessages may be lost

Page 41: Java  Messaging Services

Weblogic ImplementationWeblogic Implementation

Page 42: Java  Messaging Services

JMS XML PairingJMS XML Pairing

XML Message Type ?XML Message Type ? In practice XML messages can be placed inIn practice XML messages can be placed in

TextMessage TextMessage messages messages The pairing of XML and Java messaging The pairing of XML and Java messaging

promotes highly flexible designs that can promotes highly flexible designs that can better accommodate the rapid change that better accommodate the rapid change that distributed system face in today’s business distributed system face in today’s business environmentenvironment

Data represented in XML is polymorphic i.e Data represented in XML is polymorphic i.e same data can be used in variety of contextssame data can be used in variety of contexts

Page 43: Java  Messaging Services

JMS with J2EEJMS with J2EE

When the JMS API was first introduced in 1998, its most When the JMS API was first introduced in 1998, its most important purpose was toimportant purpose was to allow Java applications to access allow Java applications to access existing messaging-oriented middleware (MOM)systems, existing messaging-oriented middleware (MOM)systems, such as MQSeries from IBMsuch as MQSeries from IBM

Since that time, many vendors have adopted and Since that time, many vendors have adopted and implemented the JMS API,so that a JMS product can now implemented the JMS API,so that a JMS product can now provide a complete messaging capability for an enterprise.provide a complete messaging capability for an enterprise.

Page 44: Java  Messaging Services

At the1.3 release of the J2EE platform(“the J2EE 1.3 platform”), the JMS At the1.3 release of the J2EE platform(“the J2EE 1.3 platform”), the JMS API is an integral part of the platform, and application developers can API is an integral part of the platform, and application developers can use messaging with components using J2EE APIs (“J2EE components”).use messaging with components using J2EE APIs (“J2EE components”).

The JMS API in the J2EE 1.3 platform has the following features:The JMS API in the J2EE 1.3 platform has the following features: Application clients, Enterprise JavaBeans ™ (EJB ™ ) components, and Application clients, Enterprise JavaBeans ™ (EJB ™ ) components, and

webweb components can send or synchronously receive a JMS message.components can send or synchronously receive a JMS message. ApplicationApplication clients can in addition receive JMS messages clients can in addition receive JMS messages

asynchronously.asynchronously. A new kind of enterprise bean, the A new kind of enterprise bean, the messagemessage driven beandriven bean,, enables the enables the

asynchronousasynchronous consumption of messages.consumption of messages. A JMS provider may optionally implementA JMS provider may optionally implement concurrent processing of concurrent processing of

messages by message-driven beans.messages by message-driven beans. Message sends and receives can participate in distributed transactions.Message sends and receives can participate in distributed transactions.

Page 45: Java  Messaging Services

LimitationsLimitations Integration with Legacy Messaging Integration with Legacy Messaging

System(Vendor Dependent)System(Vendor Dependent) Does not address wire protocols and non JMS Does not address wire protocols and non JMS

message interchangemessage interchange It doesn't dictate a security model beyond a simple It doesn't dictate a security model beyond a simple

username and password at connection timeusername and password at connection time

Page 46: Java  Messaging Services

WheWherere Can Can WeWe Use JMS Use JMS

The provider wants the components not to depend on The provider wants the components not to depend on information about otherinformation about other components’ interfaces, so components’ interfaces, so that components can be easily replaced.that components can be easily replaced.

The provider wants the application to run whether The provider wants the application to run whether or not all components are upor not all components are up and running and running simultaneously.simultaneously.

The application business model allows a component The application business model allows a component to send information to anotherto send information to another and continue to and continue to operate without receiving an immediate response.operate without receiving an immediate response.

Page 47: Java  Messaging Services

JMS ImplementationsJMS Implementations Allaire Corporation - JRun Server BEA Systems, Inc. Brokat Technologies (formerly GemStone) IBM iPlanet (formerly Sun Microsystems, Inc. Java Message Queue) Oracle Corporation Pramati SilverStream Software, Inc. Sonic Software SpiritSoft, Inc. (formerly Push Technologies Ltd.) Talarian Corp. TIBCO Software, Inc. FioranoMQ,

Page 48: Java  Messaging Services

IBGen ScenarioIBGen Scenario

DemoDemo

WeblogicMessageQueue

Change in Properties

Timer

Client

Sends a message

Notifies

ReceivesMessage

Generate XML

Page 49: Java  Messaging Services

LinksLinks

http://java.sun.com/products/jms/http://java.sun.com/products/jms/ http://www.sonicsoftware.com/http://www.sonicsoftware.com/

Page 50: Java  Messaging Services

ThanksThanks (for the patience)(for the patience)


Recommended