SailFin-CAFE GreetingService Demo

SailFin-CAFE provides functionality to create conversation between User and MediaGroup. For instance, a simple snippet for playing an announcement to a user would look like:

   Player p = session.createParticipant(Player.class, "myPlayer");
   Conversation conv = session.createConversation(p);
   conv.addParticipant("alice@example.com");

CommunicationBeans can be used to listen media events, DTMF signals and many other events, based on which application logic can be decided.

Listener for media event when a player(announcement) is finished would be:

    @CommunicationEvent(type = CommunicationEvent.Type.MEDIAENDED)
    public void mediaEnded() {
        ----- application logic ------
    }

DTMF Signal is intercepted through CommunicationEvent type MessageArrived:

    @CommunicationEvent(type=CommunicationEvent.Type.MESSAGEARRIVED)
    void handleMessage() {
        DtmfSignal ds = (DtmfSignal) ctx.getMessage();
        String signal = ds.getSignal();
    }

At the same time Communication API makes it very handy to replace participants in a conversation. eg. Replacing a user with media group or vice-versa.

All this makes it quite simple to write applications like GreetingService. The basic idea of a GreetingService is to allow users to record messages to be played to their friends at a particular date and time.

Following image illustrates the above:

Greeting Service Example

In the above scenario Alice wants to wish Bob, so she logs in and schedules a greeting for Bob. GreetingService calls Alice for recording the message, CommunicationBean is used to play initial announcement and receive DTMF signals to start/stop recording the message. 

Once the recording is finished, an agent(GreetingAgent) is invoked to schedule the Greeting. GreetingAgent calls recepient at scheduled time and plays announcement informing about the Greeting.

Based on the DTMF response of the recepient, greeting is either played or rejected. Sender is informed about the status of the Greeting through an InstantMessage.


  • The sample can be checked out at : http://svn-mirror.glassfish.org/sailfin-cafe/trunk/cafe-samples/GreetingService/
  • Useful Links : http://weblogs.java.net/blog/binod/archive/2009/12/31/sailfin-cafe-fundamentals-communicationbeans-and-agents
  • http://weblogs.java.net/blog/binod/archive/2010/05/14/sailfin-cafe-using-presence-and-conversation-together

Comments:

hi. i would like to modify this demo into a voicemail application. Here's my scenario: alice logs in and places a call to bob. Bob's offline and alice decides to record the message. When bob logs in, an announcement's played, informing him about the message. Bob then chooses to listen to the message or not. this is what i have done, but i have some queries:

I’m still trying to modify the application but I am stuck on a few points: I am using the NetBeans IDE. Help me with correct code on the highlighted areas.

//Call bean which handles the REJECTED event and creates the presenceWatcher after recording is complete.
@CommunicationBean(type= Conversation.class)
public class CallBean {

@Context CommunicationContext<Conversation, ?, ?> ctx;
@Context CommunicationService service;
@Context CommunicationSession session;

@ParticipantEvent(type=ParticipantEvent.Type.REJECTED)
public void handleReject() {
Conversation c1 = ctx.getCommunication();
String callee = c1.getCallee().getName();
String caller = c1.getCaller().getName();
if (c1.getCallee().getName().contentEquals("bob@cafe.org")){
c1.removeParticipant(callee);
c1.removeParticipant(caller);
c1.end();
Player p = session.createParticipant(Player.class, "myPlayer");
Conversation c2 = session.createConversation(p);
c2.addParticipant("alice@.cafe.org");
}
}

if((g.getStatus().equals(GreetingStatus.RECORDING_FINISHED{

Conversation c2 = ctx.getCommunication();
String callee = c2.getCallee().getName();
String caller = c2.getCaller().getName();

Group gr = getBuddyList(caller);
gr.createOrModifyBuddy(callee, c2.getCaller().getNickName());

//get the presence status for next 7 days
PresenceWatcher pw = session.createPresenceWatcher(gr);
pw.setExpirationTime(new Date(System.currentTimeMillis() + 1000 \* 60 \* 10080));
pw.update();
}

private Group getBuddyList(String user){
String groupName = "mybuddies";
Group gr = service.getGroup(user, groupName);
if (gr == null) {
gr = service.createGroup(groupName, user);
}

return gr;
}
}
Querie 1: When I try to create the presenceWatcher after the recording is complete (i.e on the line:

if((g.getStatus().equals(GreetingStatus.RECORDING_FINISHED{

, I get a syntax error. How do I create the presenceWatcher after recording? Am stuck there. Help me with the correct API.

// the presenceBean which alerts the callee about the message.
@CommunicationBean (type= PresenceWatcher.class)
@ServiceAttributes (domainName="cafe.org", domainProxy = "<sip:127.0.0.1:5060>",xcapRoot = "http://127.0.0.1:8080/PresenceAndGroupManagementSimulator")
public class PresenceBean {

@Context CommunicationContext ctx;
@Context CommunicationSession session;
@Context CommunicationService service;

@UserProcedureEvent(type = UserProcedureEvent.Type.NOTIFICATION)
void handleNotification() {
PresenceWatcher pw = (PresenceWatcher) ctx.getUserProcedure();
PresenceMessage message = (PresenceMessage) pw.getMessage();
PeerPresentity[] modifiedPeers = message.getPeerPresentities();

for (PeerPresentity pp : modifiedPeers) {
PresenceDocument pd = pp.getPresenceDocument();
for (ServiceInformation si : pd.getAllServiceInformation()) {
//If the user is online, just
if (PresenceInformation.Status.OPEN.equals(si.getStatus())) {
if (!pw.getUserId().equalsIgnoreCase(pp.getIdentity())) {
//Play the message asking user to listen the message or quit.
Conversation c2 = (Conversation) ctx.getCommunication();
Player p = (Player) c2.getCallee();
p.start(Util.playChoice);
endWatcher(pw);
break;
}
}
}
}
}

private void endWatcher(PresenceWatcher pw) {
pw.end();
deleteGroup(pw.getUserId());
}

private void deleteGroup(String user) {
service.getGroup(user, "mybuddies").delete();
}

}
Querie 2:Is this the correct API to alert the callee about the message?

//If the user is online, just
if (PresenceInformation.Status.OPEN.equals(si.getStatus())) {
if (!pw.getUserId().equalsIgnoreCase(pp.getIdentity())) {
//Play the message asking user to listen the message or quit.
Conversation c2 = (Conversation) ctx.getCommunication();
Player p = (Player) c2.getCallee();
p.start(Util.playChoice);
endWatcher(pw);
break;

// Record wish servlet to initiate the call and the recording from the web page. An alteration of the original one.
public class RecordWish extends HttpServlet {

@Context CommunicationSession session;

/\*\*
\* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
\* @param request servlet request
\* @param response servlet response
\* @throws ServletException if a servlet-specific error occurs
\* @throws IOException if an I/O error occurs
\*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {

String sender = (String)request.getSession().getAttribute("activeUser");
String receiver = (String)request.getParameter("wishUser");

if(receiver=="bob@cafe.org") {
//Record the message from the sender.
Player p = session.createParticipant(Player.class, Util.greetingService);
Conversation c2 = session.createConversation(p, Util.recordingConversation);

Greeting g = new Greeting();
g.setSender(sender);
g.setReceiver(receiver);
g.setMessageUrl(sender, receiver);

GreetingAgent<Greeting> agent = new GreetingAgent<Greeting>();
agent.set(g);
agent.setSession(session);
c2.addAgent(Util.greetingServiceAgent, agent);

c2.addParticipant(sender);
}
}
catch (Exception ex) {
ex.printStackTrace();
} finally {
out.close();
}
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/\*\*
\* Handles the HTTP <code>GET</code> method.
\* @param request servlet request
\* @param response servlet response
\* @throws ServletException if a servlet-specific error occurs
\* @throws IOException if an I/O error occurs
\*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/\*\*
\* Handles the HTTP <code>POST</code> method.
\* @param request servlet request
\* @param response servlet response
\* @throws ServletException if a servlet-specific error occurs
\* @throws IOException if an I/O error occurs
\*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/\*\*
\* Returns a short description of the servlet.
\* @return a String containing servlet description
\*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>

}

Querie 3: I need to initiate the call from a web page after a successful log in of the caller. When the call is REJECTED, how do I prompt the recording from the web page? I am not convinced by the following code, I feel the prompt is not logical enough:

if(receiver=="bob@cafe.org") {
//Record the message from the sender.
Player p = session.createParticipant(Player.class, Util.greetingService);
Conversation c2 = session.createConversation(p, Util.recordingConversation);

// GreetingServiceBean to handle the MEDIA EVENTS of the communication session.
@CommunicationBean
public class GreetingServiceBean {
@Context CommunicationSession session;
@Context CommunicationContext ctx;

@CommunicationEvent(type = CommunicationEvent.Type.ESTABLISHED)
void handleEstablish() throws InterruptedException {
Conversation c2 = (Conversation) ctx.getCommunication();

if(c2.getName().equals(Util.recordingConversation)) {
if (c2.getCaller().getName().contains(Util.greetingService)) {
//Play the Message asking user to start/stop recording.
Player p = (Player) c2.getCaller();
p.start(Util.recordChoice);
} else if(c2.getCaller().getName().contains(Util.greetingRecorder)) {
Recorder r = (Recorder)
c2.getParticipant(Recorder.class, Util.greetingRecorder);
Greeting g = (Greeting) c2.getAgent(Util.greetingServiceAgent).get();
g.setStatus(GreetingStatus.RECORDING_STARTED);
r.start(g.getMessageUrl());
}
}

if(c2.getName().equals(Util.playRecordedMessage)) {
//set communication context for the Agent.
c2.getAgent(Util.greetingServiceAgent).setCommunicationContext(ctx);

//Play the message asking user to listen the message or quit.
Player p = (Player) c2.getCaller();
p.start(Util.playChoice);
}
}

@CommunicationEvent(type=CommunicationEvent.Type.MESSAGEARRIVED)
void handleMessage() {
DtmfSignal ds = (DtmfSignal) ctx.getMessage();
String signal = ds.getSignal();

log("DTMF signal received : " + signal);

Conversation c2 = (Conversation) ctx.getCommunication();
Agent agent = c2.getAgent(Util.greetingServiceAgent);
Greeting g = (Greeting)agent.get();

GreetingStatus status = g.getStatus();
switch (status) {
case INITIAL: {
//user has choosen to start the recording.
if (signal.equals("1")) {
Player p = (Player) c2.getCaller();
p.stop();
c2.removeParticipant(p);
Recorder r = session.createParticipant(Recorder.class,
Util.greetingRecorder);
c2.addParticipant(r);
}
break;
}
case RECORDING_STARTED: {
//user has choosen to end the recording.
if (signal.equals("2")) {
Recorder r = (Recorder) c2.getCaller();
r.stop();
g.setStatus(GreetingStatus.RECORDING_FINISHED);

//schedule the greeting.
agent.invoke();
c2.end();
}
}
case RECORDING_FINISHED: {
//user has choosen either to listen to greeting or rejected it.
if (signal.equals("1")) {
g.setStatus(GreetingStatus.PLAYING_STARTED);
agent.invoke();

String msg = "" + c2.getCallee().getName()
+ " just listened to the greeting sent by you!!";
updateSender(c2.getCaller().getName(), msg);
} else if (signal.equals("2")) {
String msg = "" + c2.getCallee().getName()
+ " has rejected your Greeting.";
updateSender(c2.getCaller().getName(), msg);
c2.end();
}
}
}
}
@CommunicationEvent(type = CommunicationEvent.Type.MEDIAENDED)
public void mediaEnded(){
Conversation c2 = (Conversation) ctx.getCommunication();
Greeting g = (Greeting) c2.getAgent(Util.greetingServiceAgent).get();
if(g.getStatus().equals(GreetingStatus.PLAYING_STARTED)) {
g.setStatus(GreetingStatus.PLAYING_FINISHED);
g.clear();
c2.end();}
}

@CommunicationEvent(type = CommunicationEvent.Type.FINISHED)
public void handleFinish() {
Conversation c2 = (Conversation) ctx.getCommunication();
Greeting g = (Greeting) c2.getAgent(Util.greetingServiceAgent).get();
if(g.getStatus().equals(GreetingStatus.PLAYING_STARTED)) {
g.setStatus(GreetingStatus.PLAYING_FINISHED);
g.clear();
}
}

private void updateSender(String sender, String message) {
IMConversation conv = session.createIMConversation(Util.greetingService);
conv.addParticipant(sender);
conv.createTextMessage(message).send();
conv.end();
}

private void log(String msg) {
System.out.println("GreetingServiceBean : " + msg);
}
}

Querie 4: I changed conversation conv to c2. I wanted to distinguish between conversation c1 and conversation c2. Is that necessary?

Querie 5: Errors are being highlighted on the following lines:

import org.glassfish.cafe.api.bean.ServiceAttributes;
@CommunicationEvent(type = CommunicationEvent.Type.MEDIAENDED).
What’s the source of these errors? I have installed the Sailfin CAFÉ addon.
I need the correct lines of code on the highlighted areas. Any other suggestions are also welcome.

please reply me by e mail

regards

tindo

Posted by tindo on July 06, 2010 at 09:30 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Mohit Gupta

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today