You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openmeetings.apache.org by "seba.wagner@gmail.com" <se...@gmail.com> on 2012/10/19 15:55:23 UTC

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Hi Maxim,

I don't understand this new code in the Rooms Entity:
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "room_id")
    private List<RoomClient> currentusers;

We calc the current users online by iterating through the Red5 Connections.
In which OpenMeetings version was it changed?

I guess you can set it Transient for XML export/import. So maybe annotate
it with:
@org.simpleframework.xml.Transient
same like roomOrganisations.

Sebastian

2012/10/19 <so...@apache.org>

> Author: solomax
> Date: Fri Oct 19 12:39:38 2012
> New Revision: 1400075
>
> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
> Log:
> Wicket: calendar form is improved
>
> Modified:
>
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
> Fri Oct 19 12:39:38 2012
> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>                 return q.getSingleResult();
>         }
>
> +       public List<Rooms> getPublicRooms() {
> +               //TypedQuery<Rooms> q =
> em.createNamedQuery("getNondeletedRooms", Rooms.class);
> +               TypedQuery<Rooms> q = em.createQuery(
> +                               "SELECT r from Rooms r LEFT JOIN FETCH
> r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY r.nameASC", Rooms.class);
> +               return q.getResultList();
> +       }
> +
> +       public List<Rooms> getOrganisationRooms(long orgId) {
> +               TypedQuery<Rooms> q = em.createQuery(
> +                               "SELECT DISTINCT c.room FROM
> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
> c.room.currentusers "
> +               + "WHERE c.organisation.organisation_id = :orgId "
> +               + "AND c.deleted = false AND c.room.deleted = false "
> +               + "AND c.organisation.deleted = false "
> +               + "ORDER BY c.room.name ASC", Rooms.class);
> +               q.setParameter("orgId", orgId);
> +               return q.getResultList();
> +       }
> +
>         public Rooms update(Rooms entity, long userId) {
>                 if (entity.getRooms_id() == null) {
>                 /* Red5SIP integration
> *******************************************************************************/
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
> Fri Oct 19 12:39:38 2012
> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>  import javax.persistence.OneToMany;
>  import javax.persistence.OneToOne;
>  import javax.persistence.Table;
> -import javax.persistence.Transient;
>
>  import org.apache.openjpa.persistence.ElementDependent;
>  import org.apache.openmeetings.persistence.beans.OmEntity;
> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>         private String name;
>
>         @Lob
> -       // @Basic(fetch=FetchType.LAZY)
>         @Column(name = "comment_field")
>         @Element(data = true, required = false)
>         private String comment;
> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>         @org.simpleframework.xml.Transient
>         private List<Rooms_Organisation> roomOrganisations = new
> ArrayList<Rooms_Organisation>();
>
> -       /*
> -        * Non persistent attributes
> -        */
> -       @Transient
> +       @OneToMany(fetch = FetchType.LAZY)
> +       @JoinColumn(name = "room_id")
>         private List<RoomClient> currentusers;
>
>         public String getComment() {
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
> Fri Oct 19 12:39:38 2012
> @@ -18,14 +18,36 @@
>   */
>  package org.apache.openmeetings.web.components.user.calendar;
>
> +import java.util.ArrayList;
> +import java.util.List;
> +
> +import
> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
> +import org.apache.openmeetings.data.conference.RoomDAO;
> +import org.apache.openmeetings.data.conference.Roommanagement;
> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>  import org.apache.openmeetings.persistence.beans.calendar.Appointment;
> +import
> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
> +import
> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
> +import org.apache.openmeetings.web.app.Application;
> +import org.apache.openmeetings.web.app.WebSession;
> +import org.apache.wicket.ajax.AjaxRequestTarget;
> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
> +import org.apache.wicket.markup.html.form.DropDownChoice;
>  import org.apache.wicket.markup.html.form.Form;
> +import org.apache.wicket.markup.html.form.PasswordTextField;
>  import org.apache.wicket.markup.html.form.RequiredTextField;
>  import org.apache.wicket.markup.html.form.TextArea;
> +import org.apache.wicket.markup.html.form.TextField;
>  import org.apache.wicket.model.IModel;
> +import org.apache.wicket.model.PropertyModel;
>
>  public class CalendarForm extends Form<Appointment> {
>         private static final long serialVersionUID = -1764738237821487526L;
> +       private boolean createRoom = true;
>
>         public CalendarForm(String id, IModel<Appointment> model) {
>                 super(id, model);
> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>
>                 add(new RequiredTextField<String>("appointmentName"));
>                 add(new TextArea<String>("appointmentDescription"));
> +               add(new TextField<String>("appointmentLocation"));
> +               add(new DateTimeField("appointmentStarttime"));
> +               add(new DateTimeField("appointmentEndtime"));
> +               final PasswordTextField pwd = new
> PasswordTextField("password");
> +               pwd.setEnabled(isPwdProtected());
> +               pwd.setOutputMarkupId(true);
> +               add(pwd);
> +
> +               add(new DropDownChoice<AppointmentReminderTyps>(
> +                               "remind"
> +                               ,
> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
> +                               , new
> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
> +
> +               final DropDownChoice<RoomTypes> roomType = new
> DropDownChoice<RoomTypes>(
> +                               "room.roomtype"
> +                               ,
> Application.getBean(Roommanagement.class).getAllRoomTypes()
> +                               , new ChoiceRenderer<RoomTypes>("name",
> "roomtypes_id"));
> +               roomType.setEnabled(createRoom);
> +               roomType.setOutputMarkupId(true);
> +               add(roomType);
> +
> +               final DropDownChoice<Rooms> room = new
> DropDownChoice<Rooms>(
> +                               "room"
> +                               , getRoomList()
> +                               , new ChoiceRenderer<Rooms>("name",
> "rooms_id"));
> +               room.setEnabled(!createRoom);
> +               room.setOutputMarkupId(true);
> +               add(room);
> +
> +               add(new AjaxCheckBox("createRoom", new
> PropertyModel<Boolean>(this, "createRoom")) {
> +                       private static final long serialVersionUID =
> -3743113990890386035L;
> +
> +                       @Override
> +                       protected void onUpdate(AjaxRequestTarget target) {
> +                               createRoom = getConvertedInput();
> +
> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
> +                       }
> +               });
> +               add(new AjaxCheckBox("isPasswordProtected") {
> +                       private static final long serialVersionUID =
> 6041200584296439976L;
> +
> +                       @Override
> +                       protected void onUpdate(AjaxRequestTarget target) {
> +
> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
> +                               pwd.setEnabled(isPwdProtected());
> +                               target.add(pwd);
> +                       }
> +               });
> +       }
> +
> +       private boolean isPwdProtected() {
> +               return
> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
> +       }
> +
> +       private List<Rooms> getRoomList() {
> +               //FIXME need to be reviewed
> +               List<Rooms> result = new ArrayList<Rooms>();
> +               RoomDAO dao = Application.getBean(RoomDAO.class);
> +               result.addAll(dao.getPublicRooms());
> +               for (Organisation_Users ou :
> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
> {
> +
> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
> +               }
> +               if (getModelObject().getRoom() != null &&
> getModelObject().getRoom().getAppointment()) { //FIXME review
> +                       result.add(getModelObject().getRoom());
> +               }
> +               return result;
>         }
>  }
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
> Fri Oct 19 12:39:38 2012
> @@ -71,7 +71,7 @@
>                                 $('#appointment').dialog({
>                                         closeOnEscape: true
>                                         , resizable: true
> -                                       , width: 400
> +                                       , width: 450
>                                         , autoOpen: false
>                                         , modal: true
>                                 });
> @@ -89,53 +89,55 @@
>                                                 <td><wicket:ommessage
> key="572" /></td>
>                                                 <td><input type="text"
> wicket:id="appointmentName" /></td>
>                                         </tr>
> -                                       <!-- tr>
> -                                               <td>&nbsp;</td>
> -                                               <td>
> -                                                       <wicket:ommessage
> key="570" /><input type="text" wicket:id="appointmentStarttime" />
> -                                                       <wicket:ommessage
> key="571" /><input type="text" wicket:id="appointmentEndtime" />
> -                                               </td>
> +                                       <tr>
> +                                               <td><wicket:ommessage
> key="570" /></td>
> +                                               <td><span
> wicket:id="appointmentStarttime"></span></td>
> +                                       </tr>
> +                                       <tr>
> +                                               <td><wicket:ommessage
> key="571" /></td>
> +                                               <td><span
> wicket:id="appointmentEndtime"></span></td>
>                                         </tr>
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="565" /></td>
> -                                               <td><select
> wicket:id="notification" ></select></td>
> +                                               <td><select
> wicket:id="remind" ></select></td>
>                                         </tr>
>                                         <tr>
>                                                 <td colspan="2"><input
> type="checkbox" wicket:id="createRoom" /><wicket:ommessage key="1509"
> /></td>
>                                         </tr>
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="619" /></td>
> -                                               <td><select
> wicket:id="roomType" ></select></td>
> +                                               <td><select
> wicket:id="room.roomtype" ></select></td>
>                                         </tr>
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="406" /></td>
>                                                 <td><select
> wicket:id="room" ></select></td>
>                                         </tr>
>                                         <tr>
> -                                               <td colspan="2"><input
> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
> key="1509" /></td>
> +                                               <td colspan="2"><input
> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
> key="524" /></td>
>                                         </tr>
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="525" /></td>
> -                                               <td><input type="text"
> wicket:id="password" /></td>
> +                                               <td><input type="password"
> wicket:id="password" /></td>
>                                         </tr>
>                                         <tr>
>                                                 <td
> colspan="2"><wicket:ommessage key="1445" /></td>
>                                         </tr>
> +                                       <!--
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="803" /></td>
>                                                 <td><select
> wicket:id="meetingMember" ></select></td>
> -                                       </tr>
> +                                       </tr -->
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="569" /></td>
>                                                 <td><input type="text"
> wicket:id="appointmentLocation" /></td>
> -                                       </tr-->
> +                                       </tr>
>                                         <tr>
>                                                 <td><wicket:ommessage
> key="573" /></td>
> -                                               <td><input type="text"
> wicket:id="appointmentDescription" /></td>
> +                                               <td><textarea
> wicket:id="appointmentDescription"></textarea></td>
>                                         </tr>
>                                         <!-- tr>
>                                                 <td colspan="2"
> style="text-align: right"><input type="button" wicket:id="save" /><input
> type="button" wicket:id="cancel" /></td>
> -                                       </tr-->
> +                                       </tr -->
>                                 </table>
>                         </form>
>                 </div>
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
> Fri Oct 19 12:39:38 2012
> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>                                 Calendar end = WebSession.getCalendar();
>
> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>
> +                               if (start.equals(end)) {
> +                                       end.add(Calendar.HOUR_OF_DAY, 1);
> +                               }
>                                 Appointment a = new Appointment();
>                                 a.setAppointmentStarttime(start.getTime());
>                                 a.setAppointmentEndtime(end.getTime());
>
>
>


-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
OK :)

On Fri, Oct 26, 2012 at 8:53 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> 2.1 should be tested first.
> Backups are not tested and all the other features need a test run.
> And I am not happy with the RoomClient in the database. We simply can't
> guarantee 150 users per room. We've never tested that. We claim currently:
> 1000 concurrent user session per server unit. That would be 10 rooms รก 100
> users.
> The question would be first: How can we test this. We need to create some
> RTMPClient and try it out.
>
> The next version 2.5 could become a hybrid version, where only the
> conference room is in Flash.
> But I would ETA this for Early 2013.
>
> Native Red5 clustering (aka "Edge/Orion") is a streamforwarding.
> It is basically a similar concept to Master/Slave but it takes it one step
> further:
> The Slaves(Edges) redirect the streams via RTMPClient.java to the Master.
> The advantage would be that a users of the same room can connect to
> different slaves.
> And you can load-balance better as you can do round-rubin to redirect
> users to the slave.
> So all your nodes in the cluster will get equally loaded with users.
>
>
> Sebastian
>
> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>
>> I also thought of removing everything already implemented in wicket.
>>
>> I would like to use clusterisation built-in wicket and maybe
>> clusterisatoon built-in red5.
>>
>> Right now I would vote for releasing 2.1 without such major changes
>> On Oct 26, 2012 8:08 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>> wrote:
>>
>>> *OK let it be implemented later :)*
>>> => I don't think you see the big picture :)
>>>
>>> I would like to have this implemented to use it also from inside Wicket.
>>> We can easily build a "hybrid" version, mixed HTML5 and Flash.
>>> Only the conference room stays in Flash.
>>> We simply redirect users from Wicket to the conference room from the
>>> room page.
>>> That way we can delete all the OpenLaszlo/LZX stuff that is currently
>>> needed for admin sections, calendar et cetera.
>>> In that way we can reduce the amount of components and we have a
>>> build-in clusterization method.
>>>
>>> Further:
>>> No db related stuff in sync method, so we can can run tests with 250
>>> participants and more in a single room.
>>> Only "master" writes to database. On the long run we will have to enable
>>> Caching to provide people with the possibility to do performance tuning.
>>> And by having the RoomClient in the session we can start to use EHCache
>>> to handle the session store, which will also give some scaling options.
>>>
>>> So from my point of view this is an opportunity to recude duplicated
>>> stuff in the UI code and to really extend it with new features.
>>> And of course such a "hybrid" can be released as new Apache Release.
>>> Lots of people are waiting for HTML5 alternative. With having an at
>>> least semi HTML5 version we might find some new community members.
>>>
>>> Sebastian
>>>
>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> 2 schedules and additional RPC calls instead of 1 table in DB ....
>>>>
>>>> OK let it be implemented later :)
>>>> On Oct 26, 2012 7:35 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>>>> wrote:
>>>>
>>>>> Can't we actually not just implement at least part of this already?
>>>>>
>>>>> My idea would be:
>>>>> To make an OpenMeetings a "slave" there will be a configuration key
>>>>> "cluster.isSlave" and "cluster.master.host"
>>>>> The slave identifies at the master by using user/pwd, those values are
>>>>> stored in the configuration table in the keys: "cluster.master.pwd" and
>>>>> "cluster.master.user" (those are Web-Service only level access credentials).
>>>>> There is a scheduler that checks every 60 seconds if cluster.isSlave
>>>>> is set to "true" (or 1).
>>>>> If yes, it will:
>>>>> a) the slave will login via SOAP/REST to the master using
>>>>> cluster.master.pwd/user/host
>>>>> b) the slave will start another scheduler, that performs every 5
>>>>> second a ping to the master.
>>>>> The ping includes current usage statistics: A list of current user
>>>>> sessions.
>>>>> A user session object could be a quite minimalistic version of the
>>>>> RoomClient to keep traffic volume low.
>>>>> In the master instance, everytime there is a ping received, it will
>>>>> store the received minimalistic session objects into own session store.
>>>>> Additionally we add a new column in the Entity "servers": Date
>>>>> lastPingTime
>>>>> This field is updated in the master database everytime a ping from the
>>>>> slave is received.
>>>>>
>>>>> If the master then wants to know how many users exist, he simply can
>>>>> ask his own session store.
>>>>> That way the RPC call for the client won't take a lot of time and no
>>>>> matter how many clients connect, you only have 1 time the traffic to gather
>>>>> the data from all slaves.
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>
>>>>>> *Slaves send a ping to the Master every XX seconds.*
>>>>>> => That way you could actually also handle a automatic failover.
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>
>>>>>> From my point of view:
>>>>>>> For the clusterization the Nodes of the Cluster should communicate
>>>>>>> via a defined API.
>>>>>>> You have a single Master, and then you try to reduce the number of
>>>>>>> API calls needed to sync between all Nodes to a minimum.
>>>>>>>
>>>>>>> But of course, same like we do now: We will have consolidated calls
>>>>>>> that build a sum accross all Nodes.
>>>>>>> The question is: What is the best mechanism is to handle such
>>>>>>> consolidated calls?
>>>>>>> The best solution might be if the Slave Nodes of the cluster
>>>>>>> register at the Master.
>>>>>>> That is basically the same what happens in every cluster. Master
>>>>>>> acts as observer, Slaves send a ping to the Master every XX seconds.
>>>>>>> And then the master can ask those nodes any kind of information he
>>>>>>> needs.
>>>>>>> Or the slaves pro-active deliver information to the Master.
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>
>>>>>>> Memory is always faster then database.
>>>>>>>> What makes this task complex is not to have the session in the
>>>>>>>> database or memory.
>>>>>>>>
>>>>>>>> Our issue is that we want to have the same information on multiple
>>>>>>>> instances.
>>>>>>>> That is basically a clusterization issue and how we will sync the
>>>>>>>> data between instances.
>>>>>>>> But I don't think that having a single database will solve
>>>>>>>> anything. You will break the whole concept of OpenJPA and other ORMs. They
>>>>>>>> are all using caching to speed up things. We just disable it now
>>>>>>>> completely. Why using an ORM if you don't use its advantages?
>>>>>>>>
>>>>>>>> And of course you will still run into issues if multiple instances
>>>>>>>> write to the same database.
>>>>>>>> That simply does not work if there is no synchronization between
>>>>>>>> the calls.
>>>>>>>>
>>>>>>>> I would have never tried to build a single database for a
>>>>>>>> clustorization solution.
>>>>>>>> From my point of view a Master/Slave solution would be much more
>>>>>>>> desirable.
>>>>>>>> The Master => Handles the database
>>>>>>>> The Slave(s) simply are redirect targets.
>>>>>>>> I mean: What do you really want to scale ?! Database access?! NO !
>>>>>>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>>>>>>> streaming is handled by multiple instances.
>>>>>>>> So actually in my mind I never thought of having the Slave(s) write
>>>>>>>> anything to the Master database. They could have their own one. My basic
>>>>>>>> concern was to have the same File-Explorer view on all clients. That is why
>>>>>>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>>>>>>> simply switch the URL and always connect to the MASTER from all conference
>>>>>>>> rooms (while RTMP is handled from via slaves).
>>>>>>>>
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>>
>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> i need Rooms.currentusers field to be filled with current users
>>>>>>>>>
>>>>>>>>> for example in the method like this:
>>>>>>>>>
>>>>>>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>>>>>>> ConferenceService.getRoomsPublic
>>>>>>>>>
>>>>>>>>> I'll add similar calls to necessary methods while implementing
>>>>>>>>> room lists on wicket.
>>>>>>>>>
>>>>>>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for
>>>>>>>>> that task, RPC is too complicated from my point of view
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> ok Thanks!
>>>>>>>>>> Sure I can write that, where do you need the result of it?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> OK
>>>>>>>>>>> no problem
>>>>>>>>>>> lets remove it
>>>>>>>>>>>
>>>>>>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> I agree however that are more comfortable way of getting
>>>>>>>>>>>> RoomClients by RoomId might be needed.
>>>>>>>>>>>> However this is a very different issue.
>>>>>>>>>>>> This is no argument for moving it to the database.
>>>>>>>>>>>> You can organize the data structure in the memory more
>>>>>>>>>>>> efficiently, make several Lists for fast access et cetera.
>>>>>>>>>>>> Or for example store it using EHCache. I thought also that it
>>>>>>>>>>>> was our plan that at some point we will externalize the session vars to
>>>>>>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>>>>>>> and externalize it to disk in case needed.
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>> the standard call to get a room client is not to get the
>>>>>>>>>>>>> roomclients by its roomid.
>>>>>>>>>>>>> The standard call to get a room client is to get the
>>>>>>>>>>>>> roomclient by its streamid !!!
>>>>>>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I just don't understand this whole discussion, we have a
>>>>>>>>>>>>> single requirement:
>>>>>>>>>>>>> Calculate the list of users per room.
>>>>>>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>>>>>>
>>>>>>>>>>>>> I don't see a need for a hybrid solution to have session
>>>>>>>>>>>>> objects twice.
>>>>>>>>>>>>> There will be multiple issues in syncing the information in
>>>>>>>>>>>>> the session objects:
>>>>>>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>>>>>>> It will not be get simpler by your solution:
>>>>>>>>>>>>> If the users connects as "Screensharing Client" your logic
>>>>>>>>>>>>> will not detect it.
>>>>>>>>>>>>> If the user connects as "Audio/Video Client" your logic will
>>>>>>>>>>>>> not detect it.
>>>>>>>>>>>>> So actually you will have multiple methods in the
>>>>>>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>>>>>>> session makes things more easy.
>>>>>>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>>>>>>> Just for having such a query we are not going to switch around
>>>>>>>>>>>>> a session object to the database.
>>>>>>>>>>>>> It just has too many drawbacks.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call
>>>>>>>>>>>>>> (no matter by client or by server) if we already have common DB and can use
>>>>>>>>>>>>>> it.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>>>>>>                 if (conn != null) {
>>>>>>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>>>>>>                         // continue;
>>>>>>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>>>>>>                         // continue;
>>>>>>>>>>>>>>                     } else {
>>>>>>>>>>>>>>                         if
>>>>>>>>>>>>>> (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>>>>>>>                             // do staff here
>>>>>>>>>>>>>>                         }
>>>>>>>>>>>>>>                     }
>>>>>>>>>>>>>>                 }
>>>>>>>>>>>>>>             }
>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> to:
>>>>>>>>>>>>>> for (RoomClient rc :
>>>>>>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>>>>>>       // do same staff here
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> we will have
>>>>>>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>>>>>>> propose the following:
>>>>>>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Is it OK?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>>>> => userC asks for the list of rooms including the number of
>>>>>>>>>>>>>>> users.
>>>>>>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>>>>>>> userC will only peform a single call, server might do
>>>>>>>>>>>>>>> mulitple calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>>>>>>> For a future iteration we might also think about a master
>>>>>>>>>>>>>>> slave principle where the slave always automatically pushes current
>>>>>>>>>>>>>>> usercount to the master, so there is no need for the master to ask for the
>>>>>>>>>>>>>>> usercount.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM
>>>>>>>>>>>>>>>> installed with same DB
>>>>>>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB
>>>>>>>>>>>>>>>> (assigned to serverB) each have 10 active users in it right now
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>>>>> In the list of rooms he can see roomA (user count can be
>>>>>>>>>>>>>>>> get by counting connections) and roomB (no user count)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>>>>>>> different servers?
>>>>>>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> The other point is of course you will have to write a
>>>>>>>>>>>>>>>>> script that will collect the number of users per room from all server
>>>>>>>>>>>>>>>>> instances and then calculate the sum of it.
>>>>>>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room
>>>>>>>>>>>>>>>>>> full of clients.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Now User enters server1 and would like to see how much
>>>>>>>>>>>>>>>>>> users in each room.
>>>>>>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> *I see no other way to get the number of users (per
>>>>>>>>>>>>>>>>>>> server)*
>>>>>>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>>>>>>> a) You count the number of connection of a certain scope
>>>>>>>>>>>>>>>>>>> and then take the sum of it
>>>>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>>>>> b) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>>>>> current session
>>>>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>>>>> c) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>>>>> current session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>>>>>>> With this method you would be able to calc the exact
>>>>>>>>>>>>>>>>>>> number of Audio/Video connection
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I'm afraid we need something like
>>>>>>>>>>>>>>>>>>>> "lightweight RoomClient" in the DB to resolve 3)
>>>>>>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but
>>>>>>>>>>>>>>>>>>>>> in memory
>>>>>>>>>>>>>>>>>>>>> 3) To have the number of users per server instance
>>>>>>>>>>>>>>>>>>>>> there is no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Practically in this case you would have to iterate
>>>>>>>>>>>>>>>>>>>>>> thorugh the connection.
>>>>>>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know
>>>>>>>>>>>>>>>>>>>>>> how many of those connection are screensharing or Audio/Video you can't
>>>>>>>>>>>>>>>>>>>>>> tell how many users exactly there are.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> If you want to share this information with others I
>>>>>>>>>>>>>>>>>>>>>> would suggest you simply add a SOAP/REST call and in that sense query the
>>>>>>>>>>>>>>>>>>>>>> number of users via a HTTP call.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to
>>>>>>>>>>>>>>>>>>>>>>> the DB since I need mechanism to retrieve how much users are currently in
>>>>>>>>>>>>>>>>>>>>>>> the room.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM,
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> We could even store it currently in the
>>>>>>>>>>>>>>>>>>>>>>>> IConnection. The Red5 framework has the similar mechanism like the static
>>>>>>>>>>>>>>>>>>>>>>>> Map that I've build.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for
>>>>>>>>>>>>>>>>>>>>>>>> the next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a
>>>>>>>>>>>>>>>>>>>>>>>> temporary solution. We can't sell this product like that and claim to have
>>>>>>>>>>>>>>>>>>>>>>>> 1000 user sessions per server unit.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>> in the database and what is needed to be done to remove it from the db
>>>>>>>>>>>>>>>>>>>>>>>> again?
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM,
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was
>>>>>>>>>>>>>>>>>>>>>>>>>> needed that you need to get the RoomClient by its public SID. However this
>>>>>>>>>>>>>>>>>>>>>>>>>> usage was quite limited.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid
>>>>>>>>>>>>>>>>>>>>>>>>>> was obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly
>>>>>>>>>>>>>>>>>>>>>>>>>> in use all over the application.
>>>>>>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration =>
>>>>>>>>>>>>>>>>>>>>>>>>>> nothing.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time
>>>>>>>>>>>>>>>>>>>>>>>>>> you speak in the video pod:
>>>>>>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it
>>>>>>>>>>>>>>>>>>>>>>>>>> will flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000
>>>>>>>>>>>>>>>>>>>>>>>>>> queries in a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <solomax666@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>> >
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1
>>>>>>>>>>>>>>>>>>>>>>>>>>> query this is why the code can work faster (after minor changes in
>>>>>>>>>>>>>>>>>>>>>>>>>>> iterating logic)
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object.
>>>>>>>>>>>>>>>>>>>>>>>>>>> But having it as DB object was the only option to have user count in the
>>>>>>>>>>>>>>>>>>>>>>>>>>> room (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will
>>>>>>>>>>>>>>>>>>>>>>>>>>> move to Wicket :)
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> single HashMap.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Database query. The performance of this single line  is ... I guess smaller
>>>>>>>>>>>>>>>>>>>>>>>>>>>> then 1 millisecond. How can you say that a "Right now I think the current
>>>>>>>>>>>>>>>>>>>>>>>>>>>> code should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that
>>>>>>>>>>>>>>>>>>>>>>>>>>>> made you implement this.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for
>>>>>>>>>>>>>>>>>>>>>>>>>>>> having the RoomClient in the database? Maybe we can resolve those
>>>>>>>>>>>>>>>>>>>>>>>>>>>> requirements differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Transient for XML export/import" is not necessary since it doesn't have
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @Element annotation
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (since DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to tune up openjpa cache and if it doesn't help will split RoomClient to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> these changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com" <se...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> second if you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> conCollection = current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> connection you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and it should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> is no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> must have refactored already a lot but I strictly did implement zero db
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> related stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> iterating through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AND c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.nameASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> == null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd = new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<RoomTypes> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<Rooms> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> final long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> final long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>               <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>               <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td colspan="2"><input type="checkbox"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="isPasswordProtected" /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td colspan="2"><input type="checkbox"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="isPasswordProtected" /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarPanel extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end = WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Appointment a = new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
2.1 should be tested first.
Backups are not tested and all the other features need a test run.
And I am not happy with the RoomClient in the database. We simply can't
guarantee 150 users per room. We've never tested that. We claim currently:
1000 concurrent user session per server unit. That would be 10 rooms รก 100
users.
The question would be first: How can we test this. We need to create some
RTMPClient and try it out.

The next version 2.5 could become a hybrid version, where only the
conference room is in Flash.
But I would ETA this for Early 2013.

Native Red5 clustering (aka "Edge/Orion") is a streamforwarding.
It is basically a similar concept to Master/Slave but it takes it one step
further:
The Slaves(Edges) redirect the streams via RTMPClient.java to the Master.
The advantage would be that a users of the same room can connect to
different slaves.
And you can load-balance better as you can do round-rubin to redirect users
to the slave.
So all your nodes in the cluster will get equally loaded with users.

Sebastian

2012/10/26 Maxim Solodovnik <so...@gmail.com>

> I also thought of removing everything already implemented in wicket.
>
> I would like to use clusterisation built-in wicket and maybe
> clusterisatoon built-in red5.
>
> Right now I would vote for releasing 2.1 without such major changes
> On Oct 26, 2012 8:08 PM, "seba.wagner@gmail.com" <se...@gmail.com>
> wrote:
>
>> *OK let it be implemented later :)*
>> => I don't think you see the big picture :)
>>
>> I would like to have this implemented to use it also from inside Wicket.
>> We can easily build a "hybrid" version, mixed HTML5 and Flash.
>> Only the conference room stays in Flash.
>> We simply redirect users from Wicket to the conference room from the room
>> page.
>> That way we can delete all the OpenLaszlo/LZX stuff that is currently
>> needed for admin sections, calendar et cetera.
>> In that way we can reduce the amount of components and we have a build-in
>> clusterization method.
>>
>> Further:
>> No db related stuff in sync method, so we can can run tests with 250
>> participants and more in a single room.
>> Only "master" writes to database. On the long run we will have to enable
>> Caching to provide people with the possibility to do performance tuning.
>> And by having the RoomClient in the session we can start to use EHCache
>> to handle the session store, which will also give some scaling options.
>>
>> So from my point of view this is an opportunity to recude duplicated
>> stuff in the UI code and to really extend it with new features.
>> And of course such a "hybrid" can be released as new Apache Release.
>> Lots of people are waiting for HTML5 alternative. With having an at least
>> semi HTML5 version we might find some new community members.
>>
>> Sebastian
>>
>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>
>>> 2 schedules and additional RPC calls instead of 1 table in DB ....
>>>
>>> OK let it be implemented later :)
>>> On Oct 26, 2012 7:35 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>>> wrote:
>>>
>>>> Can't we actually not just implement at least part of this already?
>>>>
>>>> My idea would be:
>>>> To make an OpenMeetings a "slave" there will be a configuration key
>>>> "cluster.isSlave" and "cluster.master.host"
>>>> The slave identifies at the master by using user/pwd, those values are
>>>> stored in the configuration table in the keys: "cluster.master.pwd" and
>>>> "cluster.master.user" (those are Web-Service only level access credentials).
>>>> There is a scheduler that checks every 60 seconds if cluster.isSlave is
>>>> set to "true" (or 1).
>>>> If yes, it will:
>>>> a) the slave will login via SOAP/REST to the master using
>>>> cluster.master.pwd/user/host
>>>> b) the slave will start another scheduler, that performs every 5 second
>>>> a ping to the master.
>>>> The ping includes current usage statistics: A list of current user
>>>> sessions.
>>>> A user session object could be a quite minimalistic version of the
>>>> RoomClient to keep traffic volume low.
>>>> In the master instance, everytime there is a ping received, it will
>>>> store the received minimalistic session objects into own session store.
>>>> Additionally we add a new column in the Entity "servers": Date
>>>> lastPingTime
>>>> This field is updated in the master database everytime a ping from the
>>>> slave is received.
>>>>
>>>> If the master then wants to know how many users exist, he simply can
>>>> ask his own session store.
>>>> That way the RPC call for the client won't take a lot of time and no
>>>> matter how many clients connect, you only have 1 time the traffic to gather
>>>> the data from all slaves.
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>
>>>>> *Slaves send a ping to the Master every XX seconds.*
>>>>> => That way you could actually also handle a automatic failover.
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>
>>>>> From my point of view:
>>>>>> For the clusterization the Nodes of the Cluster should communicate
>>>>>> via a defined API.
>>>>>> You have a single Master, and then you try to reduce the number of
>>>>>> API calls needed to sync between all Nodes to a minimum.
>>>>>>
>>>>>> But of course, same like we do now: We will have consolidated calls
>>>>>> that build a sum accross all Nodes.
>>>>>> The question is: What is the best mechanism is to handle such
>>>>>> consolidated calls?
>>>>>> The best solution might be if the Slave Nodes of the cluster register
>>>>>> at the Master.
>>>>>> That is basically the same what happens in every cluster. Master acts
>>>>>> as observer, Slaves send a ping to the Master every XX seconds.
>>>>>> And then the master can ask those nodes any kind of information he
>>>>>> needs.
>>>>>> Or the slaves pro-active deliver information to the Master.
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>
>>>>>> Memory is always faster then database.
>>>>>>> What makes this task complex is not to have the session in the
>>>>>>> database or memory.
>>>>>>>
>>>>>>> Our issue is that we want to have the same information on multiple
>>>>>>> instances.
>>>>>>> That is basically a clusterization issue and how we will sync the
>>>>>>> data between instances.
>>>>>>> But I don't think that having a single database will solve anything.
>>>>>>> You will break the whole concept of OpenJPA and other ORMs. They are all
>>>>>>> using caching to speed up things. We just disable it now completely. Why
>>>>>>> using an ORM if you don't use its advantages?
>>>>>>>
>>>>>>> And of course you will still run into issues if multiple instances
>>>>>>> write to the same database.
>>>>>>> That simply does not work if there is no synchronization between the
>>>>>>> calls.
>>>>>>>
>>>>>>> I would have never tried to build a single database for a
>>>>>>> clustorization solution.
>>>>>>> From my point of view a Master/Slave solution would be much more
>>>>>>> desirable.
>>>>>>> The Master => Handles the database
>>>>>>> The Slave(s) simply are redirect targets.
>>>>>>> I mean: What do you really want to scale ?! Database access?! NO !
>>>>>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>>>>>> streaming is handled by multiple instances.
>>>>>>> So actually in my mind I never thought of having the Slave(s) write
>>>>>>> anything to the Master database. They could have their own one. My basic
>>>>>>> concern was to have the same File-Explorer view on all clients. That is why
>>>>>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>>>>>> simply switch the URL and always connect to the MASTER from all conference
>>>>>>> rooms (while RTMP is handled from via slaves).
>>>>>>>
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>>
>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> i need Rooms.currentusers field to be filled with current users
>>>>>>>>
>>>>>>>> for example in the method like this:
>>>>>>>>
>>>>>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>>>>>> ConferenceService.getRoomsPublic
>>>>>>>>
>>>>>>>> I'll add similar calls to necessary methods while implementing room
>>>>>>>> lists on wicket.
>>>>>>>>
>>>>>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for
>>>>>>>> that task, RPC is too complicated from my point of view
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> ok Thanks!
>>>>>>>>> Sure I can write that, where do you need the result of it?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> OK
>>>>>>>>>> no problem
>>>>>>>>>> lets remove it
>>>>>>>>>>
>>>>>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> I agree however that are more comfortable way of getting
>>>>>>>>>>> RoomClients by RoomId might be needed.
>>>>>>>>>>> However this is a very different issue.
>>>>>>>>>>> This is no argument for moving it to the database.
>>>>>>>>>>> You can organize the data structure in the memory more
>>>>>>>>>>> efficiently, make several Lists for fast access et cetera.
>>>>>>>>>>> Or for example store it using EHCache. I thought also that it
>>>>>>>>>>> was our plan that at some point we will externalize the session vars to
>>>>>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>>>>>> and externalize it to disk in case needed.
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>> the standard call to get a room client is not to get the
>>>>>>>>>>>> roomclients by its roomid.
>>>>>>>>>>>> The standard call to get a room client is to get the roomclient
>>>>>>>>>>>> by its streamid !!!
>>>>>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>>>>>
>>>>>>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>>>>>>> requirement:
>>>>>>>>>>>> Calculate the list of users per room.
>>>>>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>>>>>
>>>>>>>>>>>> I don't see a need for a hybrid solution to have session
>>>>>>>>>>>> objects twice.
>>>>>>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>>>>>>> session objects:
>>>>>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>>>>>> It will not be get simpler by your solution:
>>>>>>>>>>>> If the users connects as "Screensharing Client" your logic will
>>>>>>>>>>>> not detect it.
>>>>>>>>>>>> If the user connects as "Audio/Video Client" your logic will
>>>>>>>>>>>> not detect it.
>>>>>>>>>>>> So actually you will have multiple methods in the
>>>>>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>>>>>
>>>>>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>>>>>> session makes things more easy.
>>>>>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>>>>>> Just for having such a query we are not going to switch around
>>>>>>>>>>>> a session object to the database.
>>>>>>>>>>>> It just has too many drawbacks.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call
>>>>>>>>>>>>> (no matter by client or by server) if we already have common DB and can use
>>>>>>>>>>>>> it.
>>>>>>>>>>>>>
>>>>>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>>>>>                 if (conn != null) {
>>>>>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>>>>>                         // continue;
>>>>>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>>>>>                         // continue;
>>>>>>>>>>>>>                     } else {
>>>>>>>>>>>>>                         if
>>>>>>>>>>>>> (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>>>>>>                             // do staff here
>>>>>>>>>>>>>                         }
>>>>>>>>>>>>>                     }
>>>>>>>>>>>>>                 }
>>>>>>>>>>>>>             }
>>>>>>>>>>>>>         }
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> to:
>>>>>>>>>>>>> for (RoomClient rc :
>>>>>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>>>>>       // do same staff here
>>>>>>>>>>>>> }
>>>>>>>>>>>>>
>>>>>>>>>>>>> we will have
>>>>>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>>>>>> propose the following:
>>>>>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>>>>>
>>>>>>>>>>>>> Is it OK?
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>>> => userC asks for the list of rooms including the number of
>>>>>>>>>>>>>> users.
>>>>>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>>>>>> userC will only peform a single call, server might do
>>>>>>>>>>>>>> mulitple calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>>>>>> For a future iteration we might also think about a master
>>>>>>>>>>>>>> slave principle where the slave always automatically pushes current
>>>>>>>>>>>>>> usercount to the master, so there is no need for the master to ask for the
>>>>>>>>>>>>>> usercount.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM
>>>>>>>>>>>>>>> installed with same DB
>>>>>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB
>>>>>>>>>>>>>>> (assigned to serverB) each have 10 active users in it right now
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>>>> In the list of rooms he can see roomA (user count can be get
>>>>>>>>>>>>>>> by counting connections) and roomB (no user count)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>>>>>> different servers?
>>>>>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The other point is of course you will have to write a
>>>>>>>>>>>>>>>> script that will collect the number of users per room from all server
>>>>>>>>>>>>>>>> instances and then calculate the sum of it.
>>>>>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full
>>>>>>>>>>>>>>>>> of clients.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Now User enters server1 and would like to see how much
>>>>>>>>>>>>>>>>> users in each room.
>>>>>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> *I see no other way to get the number of users (per
>>>>>>>>>>>>>>>>>> server)*
>>>>>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>>>>>> a) You count the number of connection of a certain scope
>>>>>>>>>>>>>>>>>> and then take the sum of it
>>>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>>>> b) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>>>> current session
>>>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>>>> c) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>>>> current session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>>>>>> With this method you would be able to calc the exact
>>>>>>>>>>>>>>>>>> number of Audio/Video connection
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I'm afraid we need something like
>>>>>>>>>>>>>>>>>>> "lightweight RoomClient" in the DB to resolve 3)
>>>>>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>>>>> 3) To have the number of users per server instance
>>>>>>>>>>>>>>>>>>>> there is no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>> >
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Practically in this case you would have to iterate
>>>>>>>>>>>>>>>>>>>>> thorugh the connection.
>>>>>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know
>>>>>>>>>>>>>>>>>>>>> how many of those connection are screensharing or Audio/Video you can't
>>>>>>>>>>>>>>>>>>>>> tell how many users exactly there are.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> If you want to share this information with others I
>>>>>>>>>>>>>>>>>>>>> would suggest you simply add a SOAP/REST call and in that sense query the
>>>>>>>>>>>>>>>>>>>>> number of users via a HTTP call.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to
>>>>>>>>>>>>>>>>>>>>>> the DB since I need mechanism to retrieve how much users are currently in
>>>>>>>>>>>>>>>>>>>>>> the room.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM,
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection.
>>>>>>>>>>>>>>>>>>>>>>> The Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for
>>>>>>>>>>>>>>>>>>>>>>> the next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a
>>>>>>>>>>>>>>>>>>>>>>> temporary solution. We can't sell this product like that and claim to have
>>>>>>>>>>>>>>>>>>>>>>> 1000 user sessions per server unit.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient
>>>>>>>>>>>>>>>>>>>>>>> in the database and what is needed to be done to remove it from the db
>>>>>>>>>>>>>>>>>>>>>>> again?
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM,
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was
>>>>>>>>>>>>>>>>>>>>>>>>> needed that you need to get the RoomClient by its public SID. However this
>>>>>>>>>>>>>>>>>>>>>>>>> usage was quite limited.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid
>>>>>>>>>>>>>>>>>>>>>>>>> was obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in
>>>>>>>>>>>>>>>>>>>>>>>>> use all over the application.
>>>>>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration =>
>>>>>>>>>>>>>>>>>>>>>>>>> nothing.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time
>>>>>>>>>>>>>>>>>>>>>>>>> you speak in the video pod:
>>>>>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it
>>>>>>>>>>>>>>>>>>>>>>>>> will flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries
>>>>>>>>>>>>>>>>>>>>>>>>> in a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query
>>>>>>>>>>>>>>>>>>>>>>>>>> this is why the code can work faster (after minor changes in iterating
>>>>>>>>>>>>>>>>>>>>>>>>>> logic)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object.
>>>>>>>>>>>>>>>>>>>>>>>>>> But having it as DB object was the only option to have user count in the
>>>>>>>>>>>>>>>>>>>>>>>>>> room (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will
>>>>>>>>>>>>>>>>>>>>>>>>>> move to Wicket :)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a
>>>>>>>>>>>>>>>>>>>>>>>>>>> single HashMap.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a
>>>>>>>>>>>>>>>>>>>>>>>>>>> Database query. The performance of this single line  is ... I guess smaller
>>>>>>>>>>>>>>>>>>>>>>>>>>> then 1 millisecond. How can you say that a "Right now I think the current
>>>>>>>>>>>>>>>>>>>>>>>>>>> code should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that
>>>>>>>>>>>>>>>>>>>>>>>>>>> made you implement this.
>>>>>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having
>>>>>>>>>>>>>>>>>>>>>>>>>>> the RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <
>>>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>> for XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (since DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to tune up openjpa cache and if it doesn't help will split RoomClient to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> these changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com" <se...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> connection you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and it should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> is no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> must have refactored already a lot but I strictly did implement zero db
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> related stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> iterating through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AND c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.nameASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<RoomTypes> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> final long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> final long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>             <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>             <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarPanel extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end = WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a = new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>


-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
I also thought of removing everything already implemented in wicket.

I would like to use clusterisation built-in wicket and maybe clusterisatoon
built-in red5.

Right now I would vote for releasing 2.1 without such major changes
On Oct 26, 2012 8:08 PM, "seba.wagner@gmail.com" <se...@gmail.com>
wrote:

> *OK let it be implemented later :)*
> => I don't think you see the big picture :)
>
> I would like to have this implemented to use it also from inside Wicket.
> We can easily build a "hybrid" version, mixed HTML5 and Flash.
> Only the conference room stays in Flash.
> We simply redirect users from Wicket to the conference room from the room
> page.
> That way we can delete all the OpenLaszlo/LZX stuff that is currently
> needed for admin sections, calendar et cetera.
> In that way we can reduce the amount of components and we have a build-in
> clusterization method.
>
> Further:
> No db related stuff in sync method, so we can can run tests with 250
> participants and more in a single room.
> Only "master" writes to database. On the long run we will have to enable
> Caching to provide people with the possibility to do performance tuning.
> And by having the RoomClient in the session we can start to use EHCache to
> handle the session store, which will also give some scaling options.
>
> So from my point of view this is an opportunity to recude duplicated stuff
> in the UI code and to really extend it with new features.
> And of course such a "hybrid" can be released as new Apache Release.
> Lots of people are waiting for HTML5 alternative. With having an at least
> semi HTML5 version we might find some new community members.
>
> Sebastian
>
> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>
>> 2 schedules and additional RPC calls instead of 1 table in DB ....
>>
>> OK let it be implemented later :)
>> On Oct 26, 2012 7:35 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>> wrote:
>>
>>> Can't we actually not just implement at least part of this already?
>>>
>>> My idea would be:
>>> To make an OpenMeetings a "slave" there will be a configuration key
>>> "cluster.isSlave" and "cluster.master.host"
>>> The slave identifies at the master by using user/pwd, those values are
>>> stored in the configuration table in the keys: "cluster.master.pwd" and
>>> "cluster.master.user" (those are Web-Service only level access credentials).
>>> There is a scheduler that checks every 60 seconds if cluster.isSlave is
>>> set to "true" (or 1).
>>> If yes, it will:
>>> a) the slave will login via SOAP/REST to the master using
>>> cluster.master.pwd/user/host
>>> b) the slave will start another scheduler, that performs every 5 second
>>> a ping to the master.
>>> The ping includes current usage statistics: A list of current user
>>> sessions.
>>> A user session object could be a quite minimalistic version of the
>>> RoomClient to keep traffic volume low.
>>> In the master instance, everytime there is a ping received, it will
>>> store the received minimalistic session objects into own session store.
>>> Additionally we add a new column in the Entity "servers": Date
>>> lastPingTime
>>> This field is updated in the master database everytime a ping from the
>>> slave is received.
>>>
>>> If the master then wants to know how many users exist, he simply can ask
>>> his own session store.
>>> That way the RPC call for the client won't take a lot of time and no
>>> matter how many clients connect, you only have 1 time the traffic to gather
>>> the data from all slaves.
>>>
>>> Sebastian
>>>
>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>>> *Slaves send a ping to the Master every XX seconds.*
>>>> => That way you could actually also handle a automatic failover.
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>
>>>> From my point of view:
>>>>> For the clusterization the Nodes of the Cluster should communicate via
>>>>> a defined API.
>>>>> You have a single Master, and then you try to reduce the number of API
>>>>> calls needed to sync between all Nodes to a minimum.
>>>>>
>>>>> But of course, same like we do now: We will have consolidated calls
>>>>> that build a sum accross all Nodes.
>>>>> The question is: What is the best mechanism is to handle such
>>>>> consolidated calls?
>>>>> The best solution might be if the Slave Nodes of the cluster register
>>>>> at the Master.
>>>>> That is basically the same what happens in every cluster. Master acts
>>>>> as observer, Slaves send a ping to the Master every XX seconds.
>>>>> And then the master can ask those nodes any kind of information he
>>>>> needs.
>>>>> Or the slaves pro-active deliver information to the Master.
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>
>>>>> Memory is always faster then database.
>>>>>> What makes this task complex is not to have the session in the
>>>>>> database or memory.
>>>>>>
>>>>>> Our issue is that we want to have the same information on multiple
>>>>>> instances.
>>>>>> That is basically a clusterization issue and how we will sync the
>>>>>> data between instances.
>>>>>> But I don't think that having a single database will solve anything.
>>>>>> You will break the whole concept of OpenJPA and other ORMs. They are all
>>>>>> using caching to speed up things. We just disable it now completely. Why
>>>>>> using an ORM if you don't use its advantages?
>>>>>>
>>>>>> And of course you will still run into issues if multiple instances
>>>>>> write to the same database.
>>>>>> That simply does not work if there is no synchronization between the
>>>>>> calls.
>>>>>>
>>>>>> I would have never tried to build a single database for a
>>>>>> clustorization solution.
>>>>>> From my point of view a Master/Slave solution would be much more
>>>>>> desirable.
>>>>>> The Master => Handles the database
>>>>>> The Slave(s) simply are redirect targets.
>>>>>> I mean: What do you really want to scale ?! Database access?! NO !
>>>>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>>>>> streaming is handled by multiple instances.
>>>>>> So actually in my mind I never thought of having the Slave(s) write
>>>>>> anything to the Master database. They could have their own one. My basic
>>>>>> concern was to have the same File-Explorer view on all clients. That is why
>>>>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>>>>> simply switch the URL and always connect to the MASTER from all conference
>>>>>> rooms (while RTMP is handled from via slaves).
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>>
>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> i need Rooms.currentusers field to be filled with current users
>>>>>>>
>>>>>>> for example in the method like this:
>>>>>>>
>>>>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>>>>> ConferenceService.getRoomsPublic
>>>>>>>
>>>>>>> I'll add similar calls to necessary methods while implementing room
>>>>>>> lists on wicket.
>>>>>>>
>>>>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>>>>>>> task, RPC is too complicated from my point of view
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> ok Thanks!
>>>>>>>> Sure I can write that, where do you need the result of it?
>>>>>>>>
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> OK
>>>>>>>>> no problem
>>>>>>>>> lets remove it
>>>>>>>>>
>>>>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> I agree however that are more comfortable way of getting
>>>>>>>>>> RoomClients by RoomId might be needed.
>>>>>>>>>> However this is a very different issue.
>>>>>>>>>> This is no argument for moving it to the database.
>>>>>>>>>> You can organize the data structure in the memory more
>>>>>>>>>> efficiently, make several Lists for fast access et cetera.
>>>>>>>>>> Or for example store it using EHCache. I thought also that it was
>>>>>>>>>> our plan that at some point we will externalize the session vars to
>>>>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>>>>> and externalize it to disk in case needed.
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>
>>>>>>>>>> the standard call to get a room client is not to get the
>>>>>>>>>>> roomclients by its roomid.
>>>>>>>>>>> The standard call to get a room client is to get the roomclient
>>>>>>>>>>> by its streamid !!!
>>>>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>>>>
>>>>>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>>>>>> requirement:
>>>>>>>>>>> Calculate the list of users per room.
>>>>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>>>>
>>>>>>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>>>>>>> twice.
>>>>>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>>>>>> session objects:
>>>>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>>>>> It will not be get simpler by your solution:
>>>>>>>>>>> If the users connects as "Screensharing Client" your logic will
>>>>>>>>>>> not detect it.
>>>>>>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>>>>>>> detect it.
>>>>>>>>>>> So actually you will have multiple methods in the
>>>>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>>>>
>>>>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>>>>> session makes things more easy.
>>>>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>>>>> Just for having such a query we are not going to switch around a
>>>>>>>>>>> session object to the database.
>>>>>>>>>>> It just has too many drawbacks.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call
>>>>>>>>>>>> (no matter by client or by server) if we already have common DB and can use
>>>>>>>>>>>> it.
>>>>>>>>>>>>
>>>>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>>>>
>>>>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>>>>                 if (conn != null) {
>>>>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>>>>                         // continue;
>>>>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>>>>                         // continue;
>>>>>>>>>>>>                     } else {
>>>>>>>>>>>>                         if
>>>>>>>>>>>> (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>>>>>                             // do staff here
>>>>>>>>>>>>                         }
>>>>>>>>>>>>                     }
>>>>>>>>>>>>                 }
>>>>>>>>>>>>             }
>>>>>>>>>>>>         }
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> to:
>>>>>>>>>>>> for (RoomClient rc :
>>>>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>>>>       // do same staff here
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> we will have
>>>>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>>>>> propose the following:
>>>>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>>>>
>>>>>>>>>>>> Is it OK?
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>> => userC asks for the list of rooms including the number of
>>>>>>>>>>>>> users.
>>>>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>>>>> For a future iteration we might also think about a master
>>>>>>>>>>>>> slave principle where the slave always automatically pushes current
>>>>>>>>>>>>> usercount to the master, so there is no need for the master to ask for the
>>>>>>>>>>>>> usercount.
>>>>>>>>>>>>>
>>>>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM
>>>>>>>>>>>>>> installed with same DB
>>>>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB
>>>>>>>>>>>>>> (assigned to serverB) each have 10 active users in it right now
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>>> In the list of rooms he can see roomA (user count can be get
>>>>>>>>>>>>>> by counting connections) and roomB (no user count)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>>>>> different servers?
>>>>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The other point is of course you will have to write a script
>>>>>>>>>>>>>>> that will collect the number of users per room from all server instances
>>>>>>>>>>>>>>> and then calculate the sum of it.
>>>>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full
>>>>>>>>>>>>>>>> of clients.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Now User enters server1 and would like to see how much
>>>>>>>>>>>>>>>> users in each room.
>>>>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> *I see no other way to get the number of users (per
>>>>>>>>>>>>>>>>> server)*
>>>>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>>>>> a) You count the number of connection of a certain scope
>>>>>>>>>>>>>>>>> and then take the sum of it
>>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>>> b) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>>> current session
>>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>>> c) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>>> current session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>>>>> With this method you would be able to calc the exact
>>>>>>>>>>>>>>>>> number of Audio/Video connection
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I'm afraid we need something like
>>>>>>>>>>>>>>>>>> "lightweight RoomClient" in the DB to resolve 3)
>>>>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>>>> 3) To have the number of users per server instance there
>>>>>>>>>>>>>>>>>>> is no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Practically in this case you would have to iterate
>>>>>>>>>>>>>>>>>>>> thorugh the connection.
>>>>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how
>>>>>>>>>>>>>>>>>>>> many of those connection are screensharing or Audio/Video you can't tell
>>>>>>>>>>>>>>>>>>>> how many users exactly there are.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> If you want to share this information with others I
>>>>>>>>>>>>>>>>>>>> would suggest you simply add a SOAP/REST call and in that sense query the
>>>>>>>>>>>>>>>>>>>> number of users via a HTTP call.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the
>>>>>>>>>>>>>>>>>>>>> DB since I need mechanism to retrieve how much users are currently in the
>>>>>>>>>>>>>>>>>>>>> room.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection.
>>>>>>>>>>>>>>>>>>>>>> The Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for
>>>>>>>>>>>>>>>>>>>>>> the next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a
>>>>>>>>>>>>>>>>>>>>>> temporary solution. We can't sell this product like that and claim to have
>>>>>>>>>>>>>>>>>>>>>> 1000 user sessions per server unit.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in
>>>>>>>>>>>>>>>>>>>>>> the database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM,
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was
>>>>>>>>>>>>>>>>>>>>>>>> needed that you need to get the RoomClient by its public SID. However this
>>>>>>>>>>>>>>>>>>>>>>>> usage was quite limited.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in
>>>>>>>>>>>>>>>>>>>>>>>> use all over the application.
>>>>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration =>
>>>>>>>>>>>>>>>>>>>>>>>> nothing.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time
>>>>>>>>>>>>>>>>>>>>>>>> you speak in the video pod:
>>>>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it
>>>>>>>>>>>>>>>>>>>>>>>> will flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries
>>>>>>>>>>>>>>>>>>>>>>>> in a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query
>>>>>>>>>>>>>>>>>>>>>>>>> this is why the code can work faster (after minor changes in iterating
>>>>>>>>>>>>>>>>>>>>>>>>> logic)
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move
>>>>>>>>>>>>>>>>>>>>>>>>> to Wicket :)
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a
>>>>>>>>>>>>>>>>>>>>>>>>>> Database query. The performance of this single line  is ... I guess smaller
>>>>>>>>>>>>>>>>>>>>>>>>>> then 1 millisecond. How can you say that a "Right now I think the current
>>>>>>>>>>>>>>>>>>>>>>>>>> code should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made
>>>>>>>>>>>>>>>>>>>>>>>>>> you implement this.
>>>>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having
>>>>>>>>>>>>>>>>>>>>>>>>>> the RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <solomax666@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>> >
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>> for XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (since DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> tune up openjpa cache and if it doesn't help will split RoomClient to the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since
>>>>>>>>>>>>>>>>>>>>>>>>>>>> these changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> is no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have refactored already a lot but I strictly did implement zero db related
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.nameASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<RoomTypes> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>             <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>             <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarPanel extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a = new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
*OK let it be implemented later :)*
=> I don't think you see the big picture :)

I would like to have this implemented to use it also from inside Wicket.
We can easily build a "hybrid" version, mixed HTML5 and Flash.
Only the conference room stays in Flash.
We simply redirect users from Wicket to the conference room from the room
page.
That way we can delete all the OpenLaszlo/LZX stuff that is currently
needed for admin sections, calendar et cetera.
In that way we can reduce the amount of components and we have a build-in
clusterization method.

Further:
No db related stuff in sync method, so we can can run tests with 250
participants and more in a single room.
Only "master" writes to database. On the long run we will have to enable
Caching to provide people with the possibility to do performance tuning.
And by having the RoomClient in the session we can start to use EHCache to
handle the session store, which will also give some scaling options.

So from my point of view this is an opportunity to recude duplicated stuff
in the UI code and to really extend it with new features.
And of course such a "hybrid" can be released as new Apache Release.
Lots of people are waiting for HTML5 alternative. With having an at least
semi HTML5 version we might find some new community members.

Sebastian

2012/10/26 Maxim Solodovnik <so...@gmail.com>

> 2 schedules and additional RPC calls instead of 1 table in DB ....
>
> OK let it be implemented later :)
> On Oct 26, 2012 7:35 PM, "seba.wagner@gmail.com" <se...@gmail.com>
> wrote:
>
>> Can't we actually not just implement at least part of this already?
>>
>> My idea would be:
>> To make an OpenMeetings a "slave" there will be a configuration key
>> "cluster.isSlave" and "cluster.master.host"
>> The slave identifies at the master by using user/pwd, those values are
>> stored in the configuration table in the keys: "cluster.master.pwd" and
>> "cluster.master.user" (those are Web-Service only level access credentials).
>> There is a scheduler that checks every 60 seconds if cluster.isSlave is
>> set to "true" (or 1).
>> If yes, it will:
>> a) the slave will login via SOAP/REST to the master using
>> cluster.master.pwd/user/host
>> b) the slave will start another scheduler, that performs every 5 second a
>> ping to the master.
>> The ping includes current usage statistics: A list of current user
>> sessions.
>> A user session object could be a quite minimalistic version of the
>> RoomClient to keep traffic volume low.
>> In the master instance, everytime there is a ping received, it will store
>> the received minimalistic session objects into own session store.
>> Additionally we add a new column in the Entity "servers": Date
>> lastPingTime
>> This field is updated in the master database everytime a ping from the
>> slave is received.
>>
>> If the master then wants to know how many users exist, he simply can ask
>> his own session store.
>> That way the RPC call for the client won't take a lot of time and no
>> matter how many clients connect, you only have 1 time the traffic to gather
>> the data from all slaves.
>>
>> Sebastian
>>
>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>
>>> *Slaves send a ping to the Master every XX seconds.*
>>> => That way you could actually also handle a automatic failover.
>>>
>>> Sebastian
>>>
>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>> From my point of view:
>>>> For the clusterization the Nodes of the Cluster should communicate via
>>>> a defined API.
>>>> You have a single Master, and then you try to reduce the number of API
>>>> calls needed to sync between all Nodes to a minimum.
>>>>
>>>> But of course, same like we do now: We will have consolidated calls
>>>> that build a sum accross all Nodes.
>>>> The question is: What is the best mechanism is to handle such
>>>> consolidated calls?
>>>> The best solution might be if the Slave Nodes of the cluster register
>>>> at the Master.
>>>> That is basically the same what happens in every cluster. Master acts
>>>> as observer, Slaves send a ping to the Master every XX seconds.
>>>> And then the master can ask those nodes any kind of information he
>>>> needs.
>>>> Or the slaves pro-active deliver information to the Master.
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>
>>>> Memory is always faster then database.
>>>>> What makes this task complex is not to have the session in the
>>>>> database or memory.
>>>>>
>>>>> Our issue is that we want to have the same information on multiple
>>>>> instances.
>>>>> That is basically a clusterization issue and how we will sync the data
>>>>> between instances.
>>>>> But I don't think that having a single database will solve anything.
>>>>> You will break the whole concept of OpenJPA and other ORMs. They are all
>>>>> using caching to speed up things. We just disable it now completely. Why
>>>>> using an ORM if you don't use its advantages?
>>>>>
>>>>> And of course you will still run into issues if multiple instances
>>>>> write to the same database.
>>>>> That simply does not work if there is no synchronization between the
>>>>> calls.
>>>>>
>>>>> I would have never tried to build a single database for a
>>>>> clustorization solution.
>>>>> From my point of view a Master/Slave solution would be much more
>>>>> desirable.
>>>>> The Master => Handles the database
>>>>> The Slave(s) simply are redirect targets.
>>>>> I mean: What do you really want to scale ?! Database access?! NO !
>>>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>>>> streaming is handled by multiple instances.
>>>>> So actually in my mind I never thought of having the Slave(s) write
>>>>> anything to the Master database. They could have their own one. My basic
>>>>> concern was to have the same File-Explorer view on all clients. That is why
>>>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>>>> simply switch the URL and always connect to the MASTER from all conference
>>>>> rooms (while RTMP is handled from via slaves).
>>>>>
>>>>>
>>>>> Sebastian
>>>>>
>>>>>
>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> i need Rooms.currentusers field to be filled with current users
>>>>>>
>>>>>> for example in the method like this:
>>>>>>
>>>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>>>> ConferenceService.getRoomsPublic
>>>>>>
>>>>>> I'll add similar calls to necessary methods while implementing room
>>>>>> lists on wicket.
>>>>>>
>>>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>>>>>> task, RPC is too complicated from my point of view
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> ok Thanks!
>>>>>>> Sure I can write that, where do you need the result of it?
>>>>>>>
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> OK
>>>>>>>> no problem
>>>>>>>> lets remove it
>>>>>>>>
>>>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> I agree however that are more comfortable way of getting
>>>>>>>>> RoomClients by RoomId might be needed.
>>>>>>>>> However this is a very different issue.
>>>>>>>>> This is no argument for moving it to the database.
>>>>>>>>> You can organize the data structure in the memory more
>>>>>>>>> efficiently, make several Lists for fast access et cetera.
>>>>>>>>> Or for example store it using EHCache. I thought also that it was
>>>>>>>>> our plan that at some point we will externalize the session vars to
>>>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>>>> and externalize it to disk in case needed.
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>
>>>>>>>>> the standard call to get a room client is not to get the
>>>>>>>>>> roomclients by its roomid.
>>>>>>>>>> The standard call to get a room client is to get the roomclient
>>>>>>>>>> by its streamid !!!
>>>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>>>
>>>>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>>>>> requirement:
>>>>>>>>>> Calculate the list of users per room.
>>>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>>>
>>>>>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>>>>>> twice.
>>>>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>>>>> session objects:
>>>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>>>> It will not be get simpler by your solution:
>>>>>>>>>> If the users connects as "Screensharing Client" your logic will
>>>>>>>>>> not detect it.
>>>>>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>>>>>> detect it.
>>>>>>>>>> So actually you will have multiple methods in the
>>>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>>>
>>>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>>>> session makes things more easy.
>>>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>>>> Just for having such a query we are not going to switch around a
>>>>>>>>>> session object to the database.
>>>>>>>>>> It just has too many drawbacks.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call
>>>>>>>>>>> (no matter by client or by server) if we already have common DB and can use
>>>>>>>>>>> it.
>>>>>>>>>>>
>>>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>>>
>>>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>>>                 if (conn != null) {
>>>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>>>                         // continue;
>>>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>>>                         // continue;
>>>>>>>>>>>                     } else {
>>>>>>>>>>>                         if (!streamid.equals(rcl.getStreamid()))
>>>>>>>>>>> {
>>>>>>>>>>>                             // do staff here
>>>>>>>>>>>                         }
>>>>>>>>>>>                     }
>>>>>>>>>>>                 }
>>>>>>>>>>>             }
>>>>>>>>>>>         }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> to:
>>>>>>>>>>> for (RoomClient rc :
>>>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>>>       // do same staff here
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> we will have
>>>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>>>> propose the following:
>>>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>>>
>>>>>>>>>>> Is it OK?
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>> => userC asks for the list of rooms including the number of
>>>>>>>>>>>> users.
>>>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>>>> For a future iteration we might also think about a master slave
>>>>>>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>>>>>>
>>>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>
>>>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed
>>>>>>>>>>>>> with same DB
>>>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB
>>>>>>>>>>>>> (assigned to serverB) each have 10 active users in it right now
>>>>>>>>>>>>>
>>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>>> In the list of rooms he can see roomA (user count can be get
>>>>>>>>>>>>> by counting connections) and roomB (no user count)
>>>>>>>>>>>>>
>>>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>>>> different servers?
>>>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The other point is of course you will have to write a script
>>>>>>>>>>>>>> that will collect the number of users per room from all server instances
>>>>>>>>>>>>>> and then calculate the sum of it.
>>>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full
>>>>>>>>>>>>>>> of clients.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Now User enters server1 and would like to see how much users
>>>>>>>>>>>>>>> in each room.
>>>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>>>> a) You count the number of connection of a certain scope
>>>>>>>>>>>>>>>> and then take the sum of it
>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>> b) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>> current session
>>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>>> c) You count the total number of RoomClients from the
>>>>>>>>>>>>>>>> current session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>>>> With this method you would be able to calc the exact number
>>>>>>>>>>>>>>>> of Audio/Video connection
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient"
>>>>>>>>>>>>>>>>> in the DB to resolve 3)
>>>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>>> 3) To have the number of users per server instance there
>>>>>>>>>>>>>>>>>> is no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Practically in this case you would have to iterate
>>>>>>>>>>>>>>>>>>> thorugh the connection.
>>>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how
>>>>>>>>>>>>>>>>>>> many of those connection are screensharing or Audio/Video you can't tell
>>>>>>>>>>>>>>>>>>> how many users exactly there are.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> If you want to share this information with others I
>>>>>>>>>>>>>>>>>>> would suggest you simply add a SOAP/REST call and in that sense query the
>>>>>>>>>>>>>>>>>>> number of users via a HTTP call.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the
>>>>>>>>>>>>>>>>>>>> DB since I need mechanism to retrieve how much users are currently in the
>>>>>>>>>>>>>>>>>>>> room.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection.
>>>>>>>>>>>>>>>>>>>>> The Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the
>>>>>>>>>>>>>>>>>>>>> next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in
>>>>>>>>>>>>>>>>>>>>> the database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM,
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed
>>>>>>>>>>>>>>>>>>>>>>> that you need to get the RoomClient by its public SID. However this usage
>>>>>>>>>>>>>>>>>>>>>>> was quite limited.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in
>>>>>>>>>>>>>>>>>>>>>>> use all over the application.
>>>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration =>
>>>>>>>>>>>>>>>>>>>>>>> nothing.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries
>>>>>>>>>>>>>>>>>>>>>>> in a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query
>>>>>>>>>>>>>>>>>>>>>>>> this is why the code can work faster (after minor changes in iterating
>>>>>>>>>>>>>>>>>>>>>>>> logic)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move
>>>>>>>>>>>>>>>>>>>>>>>> to Wicket :)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made
>>>>>>>>>>>>>>>>>>>>>>>>> you implement this.
>>>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having
>>>>>>>>>>>>>>>>>>>>>>>>> the RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient
>>>>>>>>>>>>>>>>>>>>>>>>>> for XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster
>>>>>>>>>>>>>>>>>>>>>>>>>>> (since DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to
>>>>>>>>>>>>>>>>>>>>>>>>>>> tune up openjpa cache and if it doesn't help will split RoomClient to the
>>>>>>>>>>>>>>>>>>>>>>>>>>> couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com"
>>>>>>>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second
>>>>>>>>>>>>>>>>>>>>>>>>>>>> if you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection
>>>>>>>>>>>>>>>>>>>>>>>>>>>> you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and
>>>>>>>>>>>>>>>>>>>>>>>>>>>> it should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is
>>>>>>>>>>>>>>>>>>>>>>>>>>>> no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must
>>>>>>>>>>>>>>>>>>>>>>>>>>>> have refactored already a lot but I strictly did implement zero db related
>>>>>>>>>>>>>>>>>>>>>>>>>>>> stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.nameASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<RoomTypes> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarPanel extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>


-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
2 schedules and additional RPC calls instead of 1 table in DB ....

OK let it be implemented later :)
On Oct 26, 2012 7:35 PM, "seba.wagner@gmail.com" <se...@gmail.com>
wrote:

> Can't we actually not just implement at least part of this already?
>
> My idea would be:
> To make an OpenMeetings a "slave" there will be a configuration key
> "cluster.isSlave" and "cluster.master.host"
> The slave identifies at the master by using user/pwd, those values are
> stored in the configuration table in the keys: "cluster.master.pwd" and
> "cluster.master.user" (those are Web-Service only level access credentials).
> There is a scheduler that checks every 60 seconds if cluster.isSlave is
> set to "true" (or 1).
> If yes, it will:
> a) the slave will login via SOAP/REST to the master using
> cluster.master.pwd/user/host
> b) the slave will start another scheduler, that performs every 5 second a
> ping to the master.
> The ping includes current usage statistics: A list of current user
> sessions.
> A user session object could be a quite minimalistic version of the
> RoomClient to keep traffic volume low.
> In the master instance, everytime there is a ping received, it will store
> the received minimalistic session objects into own session store.
> Additionally we add a new column in the Entity "servers": Date lastPingTime
> This field is updated in the master database everytime a ping from the
> slave is received.
>
> If the master then wants to know how many users exist, he simply can ask
> his own session store.
> That way the RPC call for the client won't take a lot of time and no
> matter how many clients connect, you only have 1 time the traffic to gather
> the data from all slaves.
>
> Sebastian
>
> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>
>> *Slaves send a ping to the Master every XX seconds.*
>> => That way you could actually also handle a automatic failover.
>>
>> Sebastian
>>
>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>
>> From my point of view:
>>> For the clusterization the Nodes of the Cluster should communicate via a
>>> defined API.
>>> You have a single Master, and then you try to reduce the number of API
>>> calls needed to sync between all Nodes to a minimum.
>>>
>>> But of course, same like we do now: We will have consolidated calls that
>>> build a sum accross all Nodes.
>>> The question is: What is the best mechanism is to handle such
>>> consolidated calls?
>>> The best solution might be if the Slave Nodes of the cluster register at
>>> the Master.
>>> That is basically the same what happens in every cluster. Master acts as
>>> observer, Slaves send a ping to the Master every XX seconds.
>>> And then the master can ask those nodes any kind of information he needs.
>>> Or the slaves pro-active deliver information to the Master.
>>>
>>> Sebastian
>>>
>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>> Memory is always faster then database.
>>>> What makes this task complex is not to have the session in the database
>>>> or memory.
>>>>
>>>> Our issue is that we want to have the same information on multiple
>>>> instances.
>>>> That is basically a clusterization issue and how we will sync the data
>>>> between instances.
>>>> But I don't think that having a single database will solve anything.
>>>> You will break the whole concept of OpenJPA and other ORMs. They are all
>>>> using caching to speed up things. We just disable it now completely. Why
>>>> using an ORM if you don't use its advantages?
>>>>
>>>> And of course you will still run into issues if multiple instances
>>>> write to the same database.
>>>> That simply does not work if there is no synchronization between the
>>>> calls.
>>>>
>>>> I would have never tried to build a single database for a
>>>> clustorization solution.
>>>> From my point of view a Master/Slave solution would be much more
>>>> desirable.
>>>> The Master => Handles the database
>>>> The Slave(s) simply are redirect targets.
>>>> I mean: What do you really want to scale ?! Database access?! NO !
>>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>>> streaming is handled by multiple instances.
>>>> So actually in my mind I never thought of having the Slave(s) write
>>>> anything to the Master database. They could have their own one. My basic
>>>> concern was to have the same File-Explorer view on all clients. That is why
>>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>>> simply switch the URL and always connect to the MASTER from all conference
>>>> rooms (while RTMP is handled from via slaves).
>>>>
>>>>
>>>> Sebastian
>>>>
>>>>
>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> i need Rooms.currentusers field to be filled with current users
>>>>>
>>>>> for example in the method like this:
>>>>>
>>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>>> ConferenceService.getRoomsPublic
>>>>>
>>>>> I'll add similar calls to necessary methods while implementing room
>>>>> lists on wicket.
>>>>>
>>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>>>>> task, RPC is too complicated from my point of view
>>>>>
>>>>>
>>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> ok Thanks!
>>>>>> Sure I can write that, where do you need the result of it?
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> OK
>>>>>>> no problem
>>>>>>> lets remove it
>>>>>>>
>>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> I agree however that are more comfortable way of getting
>>>>>>>> RoomClients by RoomId might be needed.
>>>>>>>> However this is a very different issue.
>>>>>>>> This is no argument for moving it to the database.
>>>>>>>> You can organize the data structure in the memory more efficiently,
>>>>>>>> make several Lists for fast access et cetera.
>>>>>>>> Or for example store it using EHCache. I thought also that it was
>>>>>>>> our plan that at some point we will externalize the session vars to
>>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>>> and externalize it to disk in case needed.
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>
>>>>>>>> the standard call to get a room client is not to get the
>>>>>>>>> roomclients by its roomid.
>>>>>>>>> The standard call to get a room client is to get the roomclient by
>>>>>>>>> its streamid !!!
>>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>>
>>>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>>>> requirement:
>>>>>>>>> Calculate the list of users per room.
>>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>>
>>>>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>>>>> twice.
>>>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>>>> session objects:
>>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>>> It will not be get simpler by your solution:
>>>>>>>>> If the users connects as "Screensharing Client" your logic will
>>>>>>>>> not detect it.
>>>>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>>>>> detect it.
>>>>>>>>> So actually you will have multiple methods in the
>>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>>
>>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>>> session makes things more easy.
>>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>>> Just for having such a query we are not going to switch around a
>>>>>>>>> session object to the database.
>>>>>>>>> It just has too many drawbacks.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>>>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>>>>>>
>>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>>
>>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>>                 if (conn != null) {
>>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>>                         // continue;
>>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>>                         // continue;
>>>>>>>>>>                     } else {
>>>>>>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>>>                             // do staff here
>>>>>>>>>>                         }
>>>>>>>>>>                     }
>>>>>>>>>>                 }
>>>>>>>>>>             }
>>>>>>>>>>         }
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> to:
>>>>>>>>>> for (RoomClient rc :
>>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>>       // do same staff here
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> we will have
>>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>>> propose the following:
>>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>>
>>>>>>>>>> Is it OK?
>>>>>>>>>>
>>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>> => userC asks for the list of rooms including the number of
>>>>>>>>>>> users.
>>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>>> For a future iteration we might also think about a master slave
>>>>>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>>>>>
>>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>
>>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed
>>>>>>>>>>>> with same DB
>>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB
>>>>>>>>>>>> (assigned to serverB) each have 10 active users in it right now
>>>>>>>>>>>>
>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>>>>>>> counting connections) and roomB (no user count)
>>>>>>>>>>>>
>>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>>> different servers?
>>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The other point is of course you will have to write a script
>>>>>>>>>>>>> that will collect the number of users per room from all server instances
>>>>>>>>>>>>> and then calculate the sum of it.
>>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>>>>>>> clients.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Now User enters server1 and would like to see how much users
>>>>>>>>>>>>>> in each room.
>>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>>> a) You count the number of connection of a certain scope and
>>>>>>>>>>>>>>> then take the sum of it
>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>> b) You count the total number of RoomClients from the
>>>>>>>>>>>>>>> current session
>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>> c) You count the total number of RoomClients from the
>>>>>>>>>>>>>>> current session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>>> With this method you would be able to calc the exact number
>>>>>>>>>>>>>>> of Audio/Video connection
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient"
>>>>>>>>>>>>>>>> in the DB to resolve 3)
>>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>> 3) To have the number of users per server instance there
>>>>>>>>>>>>>>>>> is no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Practically in this case you would have to iterate thorugh
>>>>>>>>>>>>>>>>>> the connection.
>>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how
>>>>>>>>>>>>>>>>>> many of those connection are screensharing or Audio/Video you can't tell
>>>>>>>>>>>>>>>>>> how many users exactly there are.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the
>>>>>>>>>>>>>>>>>>> DB since I need mechanism to retrieve how much users are currently in the
>>>>>>>>>>>>>>>>>>> room.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection.
>>>>>>>>>>>>>>>>>>>> The Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the
>>>>>>>>>>>>>>>>>>>> next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in
>>>>>>>>>>>>>>>>>>>> the database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed
>>>>>>>>>>>>>>>>>>>>>> that you need to get the RoomClient by its public SID. However this usage
>>>>>>>>>>>>>>>>>>>>>> was quite limited.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in
>>>>>>>>>>>>>>>>>>>>>> use all over the application.
>>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in
>>>>>>>>>>>>>>>>>>>>>> a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query
>>>>>>>>>>>>>>>>>>>>>>> this is why the code can work faster (after minor changes in iterating
>>>>>>>>>>>>>>>>>>>>>>> logic)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move
>>>>>>>>>>>>>>>>>>>>>>> to Wicket :)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made
>>>>>>>>>>>>>>>>>>>>>>>> you implement this.
>>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having
>>>>>>>>>>>>>>>>>>>>>>>> the RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient
>>>>>>>>>>>>>>>>>>>>>>>>> for XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since
>>>>>>>>>>>>>>>>>>>>>>>>>> DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to
>>>>>>>>>>>>>>>>>>>>>>>>>> tune up openjpa cache and if it doesn't help will split RoomClient to the
>>>>>>>>>>>>>>>>>>>>>>>>>> couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com"
>>>>>>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to
>>>>>>>>>>>>>>>>>>>>>>>>>>> sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if
>>>>>>>>>>>>>>>>>>>>>>>>>>> you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection
>>>>>>>>>>>>>>>>>>>>>>>>>>> you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and
>>>>>>>>>>>>>>>>>>>>>>>>>>> it should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is
>>>>>>>>>>>>>>>>>>>>>>>>>>> no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must
>>>>>>>>>>>>>>>>>>>>>>>>>>> have refactored already a lot but I strictly did implement zero db related
>>>>>>>>>>>>>>>>>>>>>>>>>>> stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<RoomTypes> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> != null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
oh.. I think my solution has a pitfall :)
Currently the cluster solution requires to use the same database for master
and slave right?
Actually I would like to change this too.
There is a configuration value for HTTP and for RTMP url in the config.xml.
My idea was to use this to separate Master from Slaves.
HTTP will redirect all traffic to the Master.
Slave will be only responsible for RTMP.
So the paradigma would be rather easy:
If an action requires database or file upload it will use HTTP and connect
to the master.
If an action requires sync, streaming et cetera it will use RTMP and
connect to the slave.

What do you think, can I commit a solution like this?
Are there other pitfalls?
Are there currently clusters running that need an advanced service to
update to the new design?

Sebastian

2012/10/26 seba.wagner@gmail.com <se...@gmail.com>

> Can't we actually not just implement at least part of this already?
>
> My idea would be:
> To make an OpenMeetings a "slave" there will be a configuration key
> "cluster.isSlave" and "cluster.master.host"
> The slave identifies at the master by using user/pwd, those values are
> stored in the configuration table in the keys: "cluster.master.pwd" and
> "cluster.master.user" (those are Web-Service only level access credentials).
> There is a scheduler that checks every 60 seconds if cluster.isSlave is
> set to "true" (or 1).
> If yes, it will:
> a) the slave will login via SOAP/REST to the master using
> cluster.master.pwd/user/host
> b) the slave will start another scheduler, that performs every 5 second a
> ping to the master.
> The ping includes current usage statistics: A list of current user
> sessions.
> A user session object could be a quite minimalistic version of the
> RoomClient to keep traffic volume low.
> In the master instance, everytime there is a ping received, it will store
> the received minimalistic session objects into own session store.
> Additionally we add a new column in the Entity "servers": Date lastPingTime
> This field is updated in the master database everytime a ping from the
> slave is received.
>
> If the master then wants to know how many users exist, he simply can ask
> his own session store.
> That way the RPC call for the client won't take a lot of time and no
> matter how many clients connect, you only have 1 time the traffic to gather
> the data from all slaves.
>
> Sebastian
>
> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>
> *Slaves send a ping to the Master every XX seconds.*
>> => That way you could actually also handle a automatic failover.
>>
>> Sebastian
>>
>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>
>> From my point of view:
>>> For the clusterization the Nodes of the Cluster should communicate via a
>>> defined API.
>>> You have a single Master, and then you try to reduce the number of API
>>> calls needed to sync between all Nodes to a minimum.
>>>
>>> But of course, same like we do now: We will have consolidated calls that
>>> build a sum accross all Nodes.
>>> The question is: What is the best mechanism is to handle such
>>> consolidated calls?
>>> The best solution might be if the Slave Nodes of the cluster register at
>>> the Master.
>>> That is basically the same what happens in every cluster. Master acts as
>>> observer, Slaves send a ping to the Master every XX seconds.
>>> And then the master can ask those nodes any kind of information he needs.
>>> Or the slaves pro-active deliver information to the Master.
>>>
>>> Sebastian
>>>
>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>> Memory is always faster then database.
>>>> What makes this task complex is not to have the session in the database
>>>> or memory.
>>>>
>>>> Our issue is that we want to have the same information on multiple
>>>> instances.
>>>> That is basically a clusterization issue and how we will sync the data
>>>> between instances.
>>>> But I don't think that having a single database will solve anything.
>>>> You will break the whole concept of OpenJPA and other ORMs. They are all
>>>> using caching to speed up things. We just disable it now completely. Why
>>>> using an ORM if you don't use its advantages?
>>>>
>>>> And of course you will still run into issues if multiple instances
>>>> write to the same database.
>>>> That simply does not work if there is no synchronization between the
>>>> calls.
>>>>
>>>> I would have never tried to build a single database for a
>>>> clustorization solution.
>>>> From my point of view a Master/Slave solution would be much more
>>>> desirable.
>>>> The Master => Handles the database
>>>> The Slave(s) simply are redirect targets.
>>>> I mean: What do you really want to scale ?! Database access?! NO !
>>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>>> streaming is handled by multiple instances.
>>>> So actually in my mind I never thought of having the Slave(s) write
>>>> anything to the Master database. They could have their own one. My basic
>>>> concern was to have the same File-Explorer view on all clients. That is why
>>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>>> simply switch the URL and always connect to the MASTER from all conference
>>>> rooms (while RTMP is handled from via slaves).
>>>>
>>>>
>>>> Sebastian
>>>>
>>>>
>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> i need Rooms.currentusers field to be filled with current users
>>>>>
>>>>> for example in the method like this:
>>>>>
>>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>>> ConferenceService.getRoomsPublic
>>>>>
>>>>> I'll add similar calls to necessary methods while implementing room
>>>>> lists on wicket.
>>>>>
>>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>>>>> task, RPC is too complicated from my point of view
>>>>>
>>>>>
>>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> ok Thanks!
>>>>>> Sure I can write that, where do you need the result of it?
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> OK
>>>>>>> no problem
>>>>>>> lets remove it
>>>>>>>
>>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> I agree however that are more comfortable way of getting
>>>>>>>> RoomClients by RoomId might be needed.
>>>>>>>> However this is a very different issue.
>>>>>>>> This is no argument for moving it to the database.
>>>>>>>> You can organize the data structure in the memory more efficiently,
>>>>>>>> make several Lists for fast access et cetera.
>>>>>>>> Or for example store it using EHCache. I thought also that it was
>>>>>>>> our plan that at some point we will externalize the session vars to
>>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>>> and externalize it to disk in case needed.
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>
>>>>>>>> the standard call to get a room client is not to get the
>>>>>>>>> roomclients by its roomid.
>>>>>>>>> The standard call to get a room client is to get the roomclient by
>>>>>>>>> its streamid !!!
>>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>>
>>>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>>>> requirement:
>>>>>>>>> Calculate the list of users per room.
>>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>>
>>>>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>>>>> twice.
>>>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>>>> session objects:
>>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>>> It will not be get simpler by your solution:
>>>>>>>>> If the users connects as "Screensharing Client" your logic will
>>>>>>>>> not detect it.
>>>>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>>>>> detect it.
>>>>>>>>> So actually you will have multiple methods in the
>>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>>
>>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>>> session makes things more easy.
>>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>>> Just for having such a query we are not going to switch around a
>>>>>>>>> session object to the database.
>>>>>>>>> It just has too many drawbacks.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>>>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>>>>>>
>>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>>
>>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>>                 if (conn != null) {
>>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>>                         // continue;
>>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>>                         // continue;
>>>>>>>>>>                     } else {
>>>>>>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>>>                             // do staff here
>>>>>>>>>>                         }
>>>>>>>>>>                     }
>>>>>>>>>>                 }
>>>>>>>>>>             }
>>>>>>>>>>         }
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> to:
>>>>>>>>>> for (RoomClient rc :
>>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>>       // do same staff here
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> we will have
>>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>>> propose the following:
>>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>>
>>>>>>>>>> Is it OK?
>>>>>>>>>>
>>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>> => userC asks for the list of rooms including the number of
>>>>>>>>>>> users.
>>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>>> For a future iteration we might also think about a master slave
>>>>>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>>>>>
>>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>
>>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed
>>>>>>>>>>>> with same DB
>>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB
>>>>>>>>>>>> (assigned to serverB) each have 10 active users in it right now
>>>>>>>>>>>>
>>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>>>>>>> counting connections) and roomB (no user count)
>>>>>>>>>>>>
>>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>>> different servers?
>>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The other point is of course you will have to write a script
>>>>>>>>>>>>> that will collect the number of users per room from all server instances
>>>>>>>>>>>>> and then calculate the sum of it.
>>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>>>>>>> clients.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Now User enters server1 and would like to see how much users
>>>>>>>>>>>>>> in each room.
>>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>>> a) You count the number of connection of a certain scope and
>>>>>>>>>>>>>>> then take the sum of it
>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>> b) You count the total number of RoomClients from the
>>>>>>>>>>>>>>> current session
>>>>>>>>>>>>>>> This will give you the total number of connections, no
>>>>>>>>>>>>>>> matter if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>>> c) You count the total number of RoomClients from the
>>>>>>>>>>>>>>> current session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>>> With this method you would be able to calc the exact number
>>>>>>>>>>>>>>> of Audio/Video connection
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient"
>>>>>>>>>>>>>>>> in the DB to resolve 3)
>>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>> 3) To have the number of users per server instance there
>>>>>>>>>>>>>>>>> is no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Practically in this case you would have to iterate thorugh
>>>>>>>>>>>>>>>>>> the connection.
>>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how
>>>>>>>>>>>>>>>>>> many of those connection are screensharing or Audio/Video you can't tell
>>>>>>>>>>>>>>>>>> how many users exactly there are.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the
>>>>>>>>>>>>>>>>>>> DB since I need mechanism to retrieve how much users are currently in the
>>>>>>>>>>>>>>>>>>> room.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection.
>>>>>>>>>>>>>>>>>>>> The Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the
>>>>>>>>>>>>>>>>>>>> next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in
>>>>>>>>>>>>>>>>>>>> the database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed
>>>>>>>>>>>>>>>>>>>>>> that you need to get the RoomClient by its public SID. However this usage
>>>>>>>>>>>>>>>>>>>>>> was quite limited.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in
>>>>>>>>>>>>>>>>>>>>>> use all over the application.
>>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in
>>>>>>>>>>>>>>>>>>>>>> a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query
>>>>>>>>>>>>>>>>>>>>>>> this is why the code can work faster (after minor changes in iterating
>>>>>>>>>>>>>>>>>>>>>>> logic)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move
>>>>>>>>>>>>>>>>>>>>>>> to Wicket :)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made
>>>>>>>>>>>>>>>>>>>>>>>> you implement this.
>>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having
>>>>>>>>>>>>>>>>>>>>>>>> the RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient
>>>>>>>>>>>>>>>>>>>>>>>>> for XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since
>>>>>>>>>>>>>>>>>>>>>>>>>> DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to
>>>>>>>>>>>>>>>>>>>>>>>>>> tune up openjpa cache and if it doesn't help will split RoomClient to the
>>>>>>>>>>>>>>>>>>>>>>>>>> couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com"
>>>>>>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to
>>>>>>>>>>>>>>>>>>>>>>>>>>> sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if
>>>>>>>>>>>>>>>>>>>>>>>>>>> you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection
>>>>>>>>>>>>>>>>>>>>>>>>>>> you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and
>>>>>>>>>>>>>>>>>>>>>>>>>>> it should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is
>>>>>>>>>>>>>>>>>>>>>>>>>>> no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must
>>>>>>>>>>>>>>>>>>>>>>>>>>> have refactored already a lot but I strictly did implement zero db related
>>>>>>>>>>>>>>>>>>>>>>>>>>> stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<RoomTypes> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> != null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
Can't we actually not just implement at least part of this already?

My idea would be:
To make an OpenMeetings a "slave" there will be a configuration key
"cluster.isSlave" and "cluster.master.host"
The slave identifies at the master by using user/pwd, those values are
stored in the configuration table in the keys: "cluster.master.pwd" and
"cluster.master.user" (those are Web-Service only level access credentials).
There is a scheduler that checks every 60 seconds if cluster.isSlave is set
to "true" (or 1).
If yes, it will:
a) the slave will login via SOAP/REST to the master using
cluster.master.pwd/user/host
b) the slave will start another scheduler, that performs every 5 second a
ping to the master.
The ping includes current usage statistics: A list of current user sessions.
A user session object could be a quite minimalistic version of the
RoomClient to keep traffic volume low.
In the master instance, everytime there is a ping received, it will store
the received minimalistic session objects into own session store.
Additionally we add a new column in the Entity "servers": Date lastPingTime
This field is updated in the master database everytime a ping from the
slave is received.

If the master then wants to know how many users exist, he simply can ask
his own session store.
That way the RPC call for the client won't take a lot of time and no matter
how many clients connect, you only have 1 time the traffic to gather the
data from all slaves.

Sebastian

2012/10/26 seba.wagner@gmail.com <se...@gmail.com>

> *Slaves send a ping to the Master every XX seconds.*
> => That way you could actually also handle a automatic failover.
>
> Sebastian
>
> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>
> From my point of view:
>> For the clusterization the Nodes of the Cluster should communicate via a
>> defined API.
>> You have a single Master, and then you try to reduce the number of API
>> calls needed to sync between all Nodes to a minimum.
>>
>> But of course, same like we do now: We will have consolidated calls that
>> build a sum accross all Nodes.
>> The question is: What is the best mechanism is to handle such
>> consolidated calls?
>> The best solution might be if the Slave Nodes of the cluster register at
>> the Master.
>> That is basically the same what happens in every cluster. Master acts as
>> observer, Slaves send a ping to the Master every XX seconds.
>> And then the master can ask those nodes any kind of information he needs.
>> Or the slaves pro-active deliver information to the Master.
>>
>> Sebastian
>>
>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>
>> Memory is always faster then database.
>>> What makes this task complex is not to have the session in the database
>>> or memory.
>>>
>>> Our issue is that we want to have the same information on multiple
>>> instances.
>>> That is basically a clusterization issue and how we will sync the data
>>> between instances.
>>> But I don't think that having a single database will solve anything. You
>>> will break the whole concept of OpenJPA and other ORMs. They are all using
>>> caching to speed up things. We just disable it now completely. Why using an
>>> ORM if you don't use its advantages?
>>>
>>> And of course you will still run into issues if multiple instances write
>>> to the same database.
>>> That simply does not work if there is no synchronization between the
>>> calls.
>>>
>>> I would have never tried to build a single database for a clustorization
>>> solution.
>>> From my point of view a Master/Slave solution would be much more
>>> desirable.
>>> The Master => Handles the database
>>> The Slave(s) simply are redirect targets.
>>> I mean: What do you really want to scale ?! Database access?! NO !
>>> Streaming is CPU/memory intensive. So what you want to scale is that the
>>> streaming is handled by multiple instances.
>>> So actually in my mind I never thought of having the Slave(s) write
>>> anything to the Master database. They could have their own one. My basic
>>> concern was to have the same File-Explorer view on all clients. That is why
>>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>>> simply switch the URL and always connect to the MASTER from all conference
>>> rooms (while RTMP is handled from via slaves).
>>>
>>>
>>> Sebastian
>>>
>>>
>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> i need Rooms.currentusers field to be filled with current users
>>>>
>>>> for example in the method like this:
>>>>
>>>> ConferenceService.getRoomsByOrganisationWithoutType
>>>> ConferenceService.getRoomsPublic
>>>>
>>>> I'll add similar calls to necessary methods while implementing room
>>>> lists on wicket.
>>>>
>>>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>>>> task, RPC is too complicated from my point of view
>>>>
>>>>
>>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> ok Thanks!
>>>>> Sure I can write that, where do you need the result of it?
>>>>>
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> OK
>>>>>> no problem
>>>>>> lets remove it
>>>>>>
>>>>>> can you please write RPC call performing user count retrieving?
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> I agree however that are more comfortable way of getting RoomClients
>>>>>>> by RoomId might be needed.
>>>>>>> However this is a very different issue.
>>>>>>> This is no argument for moving it to the database.
>>>>>>> You can organize the data structure in the memory more efficiently,
>>>>>>> make several Lists for fast access et cetera.
>>>>>>> Or for example store it using EHCache. I thought also that it was
>>>>>>> our plan that at some point we will externalize the session vars to
>>>>>>> EHCache, so that you have the chance to configure the session storage size
>>>>>>> and externalize it to disk in case needed.
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>
>>>>>>> the standard call to get a room client is not to get the roomclients
>>>>>>>> by its roomid.
>>>>>>>> The standard call to get a room client is to get the roomclient by
>>>>>>>> its streamid !!!
>>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>>
>>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>>> requirement:
>>>>>>>> Calculate the list of users per room.
>>>>>>>> And now we need to switch a session object to the database?
>>>>>>>>
>>>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>>>> twice.
>>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>>> session objects:
>>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>>> It will not be get simpler by your solution:
>>>>>>>> If the users connects as "Screensharing Client" your logic will not
>>>>>>>> detect it.
>>>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>>>> detect it.
>>>>>>>> So actually you will have multiple methods in the
>>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>>
>>>>>>>> I really don't think splitting up that logic to database and
>>>>>>>> session makes things more easy.
>>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>>> ROOMATTENDEE" ;)
>>>>>>>> Just for having such a query we are not going to switch around a
>>>>>>>> session object to the database.
>>>>>>>> It just has too many drawbacks.
>>>>>>>>
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>>>>>
>>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>>
>>>>>>>>> I still think that if code will be changed from
>>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>>                 if (conn != null) {
>>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>>                                     .getClient().getId());
>>>>>>>>>                     if (rcl == null) {
>>>>>>>>>                         // continue;
>>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>>                         // continue;
>>>>>>>>>                     } else {
>>>>>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>>                             // do staff here
>>>>>>>>>                         }
>>>>>>>>>                     }
>>>>>>>>>                 }
>>>>>>>>>             }
>>>>>>>>>         }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> to:
>>>>>>>>> for (RoomClient rc :
>>>>>>>>> clientListManager.getClientListByRoom(roomId)) {
>>>>>>>>>       // do same staff here
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> we will have
>>>>>>>>> 1) only one DB call per broadcast
>>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> To implement your solution and remove RoomClient from DB, I
>>>>>>>>> propose the following:
>>>>>>>>> 1) remove RoomClient from DB
>>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>>> info while getting list of users currently in room)
>>>>>>>>>
>>>>>>>>> Is it OK?
>>>>>>>>>
>>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>> => userC asks for the list of rooms including the number of users.
>>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>>> For a future iteration we might also think about a master slave
>>>>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>>>>
>>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>
>>>>>>>>>>> Imagine the following situation:
>>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed
>>>>>>>>>>> with same DB
>>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned
>>>>>>>>>>> to serverB) each have 10 active users in it right now
>>>>>>>>>>>
>>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>>>>>> counting connections) and roomB (no user count)
>>>>>>>>>>>
>>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> How do you handle rooms in general in that solution, is a
>>>>>>>>>>>> single room always on the same server instance.
>>>>>>>>>>>> Or in other words:
>>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>>> different servers?
>>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>>
>>>>>>>>>>>> The other point is of course you will have to write a script
>>>>>>>>>>>> that will collect the number of users per room from all server instances
>>>>>>>>>>>> and then calculate the sum of it.
>>>>>>>>>>>> I would collect this on the server side and then give the
>>>>>>>>>>>> client just the result of it. For the client it would look like a single
>>>>>>>>>>>> RPC call, while on server side, the server asks each instance for its usage
>>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>>>>>> clients.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Now User enters server1 and would like to see how much users
>>>>>>>>>>>>> in each room.
>>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>>> number:
>>>>>>>>>>>>>> a) You count the number of connection of a certain scope and
>>>>>>>>>>>>>> then take the sum of it
>>>>>>>>>>>>>> This will give you the total number of connections, no matter
>>>>>>>>>>>>>> if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>>>>>>>> session
>>>>>>>>>>>>>> This will give you the total number of connections, no matter
>>>>>>>>>>>>>> if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>>> With this method you would be able to calc the exact number
>>>>>>>>>>>>>> of Audio/Video connection
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient"
>>>>>>>>>>>>>>> in the DB to resolve 3)
>>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>> 3) To have the number of users per server instance there is
>>>>>>>>>>>>>>>> no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Practically in this case you would have to iterate thorugh
>>>>>>>>>>>>>>>>> the connection.
>>>>>>>>>>>>>>>>> You could also call IConnection => getConnection =>
>>>>>>>>>>>>>>>>> getSize.
>>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how
>>>>>>>>>>>>>>>>> many of those connection are screensharing or Audio/Video you can't tell
>>>>>>>>>>>>>>>>> how many users exactly there are.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB
>>>>>>>>>>>>>>>>>> since I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection. The
>>>>>>>>>>>>>>>>>>> Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the
>>>>>>>>>>>>>>>>>>> next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in
>>>>>>>>>>>>>>>>>>> the database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be
>>>>>>>>>>>>>>>>>>>> removed in the future.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed
>>>>>>>>>>>>>>>>>>>>> that you need to get the RoomClient by its public SID. However this usage
>>>>>>>>>>>>>>>>>>>>> was quite limited.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use
>>>>>>>>>>>>>>>>>>>>> all over the application.
>>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB
>>>>>>>>>>>>>>>>>>>>> query.
>>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in
>>>>>>>>>>>>>>>>>>>>> a SINGLE SECOND
>>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query
>>>>>>>>>>>>>>>>>>>>>> this is why the code can work faster (after minor changes in iterating
>>>>>>>>>>>>>>>>>>>>>> logic)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM,
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a
>>>>>>>>>>>>>>>>>>>>>>> HashMap stored in the memory is slower then doing a single query for every
>>>>>>>>>>>>>>>>>>>>>>> entry of the map ?
>>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made
>>>>>>>>>>>>>>>>>>>>>>> you implement this.
>>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for
>>>>>>>>>>>>>>>>>>>>>>>> XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I
>>>>>>>>>>>>>>>>>>>>>>>>> implemented cluster.
>>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since
>>>>>>>>>>>>>>>>>>>>>>>>> DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of
>>>>>>>>>>>>>>>>>>>>>>>>> RommsClient hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to
>>>>>>>>>>>>>>>>>>>>>>>>> tune up openjpa cache and if it doesn't help will split RoomClient to the
>>>>>>>>>>>>>>>>>>>>>>>>> couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to
>>>>>>>>>>>>>>>>>>>>>>>>>> determine the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to
>>>>>>>>>>>>>>>>>>>>>>>>>> sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if
>>>>>>>>>>>>>>>>>>>>>>>>>> you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection
>>>>>>>>>>>>>>>>>>>>>>>>>> you will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is
>>>>>>>>>>>>>>>>>>>>>>>>>> no chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must
>>>>>>>>>>>>>>>>>>>>>>>>>> have refactored already a lot but I strictly did implement zero db related
>>>>>>>>>>>>>>>>>>>>>>>>>> stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to
>>>>>>>>>>>>>>>>>>>>>>>>>> trigger db actions.However I don't think having two times the RoomClient
>>>>>>>>>>>>>>>>>>>>>>>>>> stored (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISTINCT c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN
>>>>>>>>>>>>>>>>>>>>>>>>>>>> FETCH c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> room = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom()
>>>>>>>>>>>>>>>>>>>>>>>>>>>> != null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 400
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> width: 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>>> modal: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>         <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a =
>>>>>>>>>>>>>>>>>>>>>>>>>>>> new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
*Slaves send a ping to the Master every XX seconds.*
=> That way you could actually also handle a automatic failover.

Sebastian

2012/10/26 seba.wagner@gmail.com <se...@gmail.com>

> From my point of view:
> For the clusterization the Nodes of the Cluster should communicate via a
> defined API.
> You have a single Master, and then you try to reduce the number of API
> calls needed to sync between all Nodes to a minimum.
>
> But of course, same like we do now: We will have consolidated calls that
> build a sum accross all Nodes.
> The question is: What is the best mechanism is to handle such consolidated
> calls?
> The best solution might be if the Slave Nodes of the cluster register at
> the Master.
> That is basically the same what happens in every cluster. Master acts as
> observer, Slaves send a ping to the Master every XX seconds.
> And then the master can ask those nodes any kind of information he needs.
> Or the slaves pro-active deliver information to the Master.
>
> Sebastian
>
> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>
> Memory is always faster then database.
>> What makes this task complex is not to have the session in the database
>> or memory.
>>
>> Our issue is that we want to have the same information on multiple
>> instances.
>> That is basically a clusterization issue and how we will sync the data
>> between instances.
>> But I don't think that having a single database will solve anything. You
>> will break the whole concept of OpenJPA and other ORMs. They are all using
>> caching to speed up things. We just disable it now completely. Why using an
>> ORM if you don't use its advantages?
>>
>> And of course you will still run into issues if multiple instances write
>> to the same database.
>> That simply does not work if there is no synchronization between the
>> calls.
>>
>> I would have never tried to build a single database for a clustorization
>> solution.
>> From my point of view a Master/Slave solution would be much more
>> desirable.
>> The Master => Handles the database
>> The Slave(s) simply are redirect targets.
>> I mean: What do you really want to scale ?! Database access?! NO !
>> Streaming is CPU/memory intensive. So what you want to scale is that the
>> streaming is handled by multiple instances.
>> So actually in my mind I never thought of having the Slave(s) write
>> anything to the Master database. They could have their own one. My basic
>> concern was to have the same File-Explorer view on all clients. That is why
>> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
>> simply switch the URL and always connect to the MASTER from all conference
>> rooms (while RTMP is handled from via slaves).
>>
>>
>> Sebastian
>>
>>
>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>
>>> i need Rooms.currentusers field to be filled with current users
>>>
>>> for example in the method like this:
>>>
>>> ConferenceService.getRoomsByOrganisationWithoutType
>>> ConferenceService.getRoomsPublic
>>>
>>> I'll add similar calls to necessary methods while implementing room
>>> lists on wicket.
>>>
>>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>>> task, RPC is too complicated from my point of view
>>>
>>>
>>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> ok Thanks!
>>>> Sure I can write that, where do you need the result of it?
>>>>
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> OK
>>>>> no problem
>>>>> lets remove it
>>>>>
>>>>> can you please write RPC call performing user count retrieving?
>>>>>
>>>>>
>>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> I agree however that are more comfortable way of getting RoomClients
>>>>>> by RoomId might be needed.
>>>>>> However this is a very different issue.
>>>>>> This is no argument for moving it to the database.
>>>>>> You can organize the data structure in the memory more efficiently,
>>>>>> make several Lists for fast access et cetera.
>>>>>> Or for example store it using EHCache. I thought also that it was our
>>>>>> plan that at some point we will externalize the session vars to EHCache, so
>>>>>> that you have the chance to configure the session storage size and
>>>>>> externalize it to disk in case needed.
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>
>>>>>> the standard call to get a room client is not to get the roomclients
>>>>>>> by its roomid.
>>>>>>> The standard call to get a room client is to get the roomclient by
>>>>>>> its streamid !!!
>>>>>>> And this call is done for every RoomClient per sync method.
>>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>>> I thought I have tried to explain the calculation.
>>>>>>>
>>>>>>> I just don't understand this whole discussion, we have a single
>>>>>>> requirement:
>>>>>>> Calculate the list of users per room.
>>>>>>> And now we need to switch a session object to the database?
>>>>>>>
>>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>>> twice.
>>>>>>> There will be multiple issues in syncing the information in the
>>>>>>> session objects:
>>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>>> It will not be get simpler by your solution:
>>>>>>> If the users connects as "Screensharing Client" your logic will not
>>>>>>> detect it.
>>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>>> detect it.
>>>>>>> So actually you will have multiple methods in the
>>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>>
>>>>>>> I really don't think splitting up that logic to database and session
>>>>>>> makes things more easy.
>>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>>> ROOMATTENDEE" ;)
>>>>>>> Just for having such a query we are not going to switch around a
>>>>>>> session object to the database.
>>>>>>> It just has too many drawbacks.
>>>>>>>
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>>>>
>>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>>
>>>>>>>> I still think that if code will be changed from
>>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>>             for (IConnection conn : conset) {
>>>>>>>>                 if (conn != null) {
>>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>>                             .getClientByStreamId(conn
>>>>>>>>                                     .getClient().getId());
>>>>>>>>                     if (rcl == null) {
>>>>>>>>                         // continue;
>>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>>                         // continue;
>>>>>>>>                     } else {
>>>>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>>>>                             // do staff here
>>>>>>>>                         }
>>>>>>>>                     }
>>>>>>>>                 }
>>>>>>>>             }
>>>>>>>>         }
>>>>>>>>
>>>>>>>>
>>>>>>>> to:
>>>>>>>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId))
>>>>>>>> {
>>>>>>>>       // do same staff here
>>>>>>>> }
>>>>>>>>
>>>>>>>> we will have
>>>>>>>> 1) only one DB call per broadcast
>>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>>
>>>>>>>>
>>>>>>>> To implement your solution and remove RoomClient from DB, I propose
>>>>>>>> the following:
>>>>>>>> 1) remove RoomClient from DB
>>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>>> info while getting list of users currently in room)
>>>>>>>>
>>>>>>>> Is it OK?
>>>>>>>>
>>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>> => userC asks for the list of rooms including the number of users.
>>>>>>>>> The server side will calc the users per room. Either by
>>>>>>>>> calculating the rooms locally, or by perrforming a RPC call to the
>>>>>>>>> connected server to get the list of current usercount per room.
>>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>>> So there is no multiple calls needed.
>>>>>>>>> For a future iteration we might also think about a master slave
>>>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>>>
>>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>
>>>>>>>>>> Imagine the following situation:
>>>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed
>>>>>>>>>> with same DB
>>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned
>>>>>>>>>> to serverB) each have 10 active users in it right now
>>>>>>>>>>
>>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>>>>> counting connections) and roomB (no user count)
>>>>>>>>>>
>>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> How do you handle rooms in general in that solution, is a single
>>>>>>>>>>> room always on the same server instance.
>>>>>>>>>>> Or in other words:
>>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>>> different servers?
>>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>>> You can't stream a video from server instance 1 and from
>>>>>>>>>>> instance 2 at the same time.
>>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>>
>>>>>>>>>>> The other point is of course you will have to write a script
>>>>>>>>>>> that will collect the number of users per room from all server instances
>>>>>>>>>>> and then calculate the sum of it.
>>>>>>>>>>> I would collect this on the server side and then give the client
>>>>>>>>>>> just the result of it. For the client it would look like a single RPC call,
>>>>>>>>>>> while on server side, the server asks each instance for its usage
>>>>>>>>>>> numbers/statistics.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>>>>> clients.
>>>>>>>>>>>>
>>>>>>>>>>>> Now User enters server1 and would like to see how much users in
>>>>>>>>>>>> each room.
>>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>>> regarding second one.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>>>> => There are at least three alternative ways to get this
>>>>>>>>>>>>> number:
>>>>>>>>>>>>> a) You count the number of connection of a certain scope and
>>>>>>>>>>>>> then take the sum of it
>>>>>>>>>>>>> This will give you the total number of connections, no matter
>>>>>>>>>>>>> if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>>>>>>> session
>>>>>>>>>>>>> This will give you the total number of connections, no matter
>>>>>>>>>>>>> if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>>> With this method you would be able to calc the exact number of
>>>>>>>>>>>>> Audio/Video connection
>>>>>>>>>>>>>
>>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in
>>>>>>>>>>>>>> the DB to resolve 3)
>>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in
>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>> 3) To have the number of users per server instance there is
>>>>>>>>>>>>>>> no need to have the RoomClient in the database.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Practically in this case you would have to iterate thorugh
>>>>>>>>>>>>>>>> the connection.
>>>>>>>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how
>>>>>>>>>>>>>>>> many of those connection are screensharing or Audio/Video you can't tell
>>>>>>>>>>>>>>>> how many users exactly there are.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB
>>>>>>>>>>>>>>>>> since I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection. The
>>>>>>>>>>>>>>>>>> Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the
>>>>>>>>>>>>>>>>>> next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed
>>>>>>>>>>>>>>>>>>> in the future.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed
>>>>>>>>>>>>>>>>>>>> that you need to get the RoomClient by its public SID. However this usage
>>>>>>>>>>>>>>>>>>>> was quite limited.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use
>>>>>>>>>>>>>>>>>>>> all over the application.
>>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>>>>>>>> And if you iterate like described through all
>>>>>>>>>>>>>>>>>>>> connection (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this
>>>>>>>>>>>>>>>>>>>>> is why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for
>>>>>>>>>>>>>>>>>>>>>>> XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since
>>>>>>>>>>>>>>>>>>>>>>>> DB is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient
>>>>>>>>>>>>>>>>>>>>>>>> hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to
>>>>>>>>>>>>>>>>>>>>>>>> tune up openjpa cache and if it doesn't help will split RoomClient to the
>>>>>>>>>>>>>>>>>>>>>>>> couple of objects and/or will create hashtable in parallel to speed up
>>>>>>>>>>>>>>>>>>>>>>>> things.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine
>>>>>>>>>>>>>>>>>>>>>>>>> the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to
>>>>>>>>>>>>>>>>>>>>>>>>> sync messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if
>>>>>>>>>>>>>>>>>>>>>>>>> you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you
>>>>>>>>>>>>>>>>>>>>>>>>> will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the
>>>>>>>>>>>>>>>>>>>>>>>>> WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must
>>>>>>>>>>>>>>>>>>>>>>>>> have refactored already a lot but I strictly did implement zero db related
>>>>>>>>>>>>>>>>>>>>>>>>> stuff in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger
>>>>>>>>>>>>>>>>>>>>>>>>> db actions.However I don't think having two times the RoomClient stored
>>>>>>>>>>>>>>>>>>>>>>>>> (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted =
>>>>>>>>>>>>>>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() ==
>>>>>>>>>>>>>>>>>>>>>>>>>>> null) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd =
>>>>>>>>>>>>>>>>>>>>>>>>>>> new PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room
>>>>>>>>>>>>>>>>>>>>>>>>>>> = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final
>>>>>>>>>>>>>>>>>>>>>>>>>>> long serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom()
>>>>>>>>>>>>>>>>>>>>>>>>>>> != null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       , width:
>>>>>>>>>>>>>>>>>>>>>>>>>>> 400
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       , width:
>>>>>>>>>>>>>>>>>>>>>>>>>>> 450
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         , modal:
>>>>>>>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>         <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>>         <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a =
>>>>>>>>>>>>>>>>>>>>>>>>>>> new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
>From my point of view:
For the clusterization the Nodes of the Cluster should communicate via a
defined API.
You have a single Master, and then you try to reduce the number of API
calls needed to sync between all Nodes to a minimum.

But of course, same like we do now: We will have consolidated calls that
build a sum accross all Nodes.
The question is: What is the best mechanism is to handle such consolidated
calls?
The best solution might be if the Slave Nodes of the cluster register at
the Master.
That is basically the same what happens in every cluster. Master acts as
observer, Slaves send a ping to the Master every XX seconds.
And then the master can ask those nodes any kind of information he needs.
Or the slaves pro-active deliver information to the Master.

Sebastian

2012/10/26 seba.wagner@gmail.com <se...@gmail.com>

> Memory is always faster then database.
> What makes this task complex is not to have the session in the database or
> memory.
>
> Our issue is that we want to have the same information on multiple
> instances.
> That is basically a clusterization issue and how we will sync the data
> between instances.
> But I don't think that having a single database will solve anything. You
> will break the whole concept of OpenJPA and other ORMs. They are all using
> caching to speed up things. We just disable it now completely. Why using an
> ORM if you don't use its advantages?
>
> And of course you will still run into issues if multiple instances write
> to the same database.
> That simply does not work if there is no synchronization between the calls.
>
> I would have never tried to build a single database for a clustorization
> solution.
> From my point of view a Master/Slave solution would be much more desirable.
> The Master => Handles the database
> The Slave(s) simply are redirect targets.
> I mean: What do you really want to scale ?! Database access?! NO !
> Streaming is CPU/memory intensive. So what you want to scale is that the
> streaming is handled by multiple instances.
> So actually in my mind I never thought of having the Slave(s) write
> anything to the Master database. They could have their own one. My basic
> concern was to have the same File-Explorer view on all clients. That is why
> I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
> simply switch the URL and always connect to the MASTER from all conference
> rooms (while RTMP is handled from via slaves).
>
>
> Sebastian
>
>
> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>
>> i need Rooms.currentusers field to be filled with current users
>>
>> for example in the method like this:
>>
>> ConferenceService.getRoomsByOrganisationWithoutType
>> ConferenceService.getRoomsPublic
>>
>> I'll add similar calls to necessary methods while implementing room lists
>> on wicket.
>>
>> OFFTOPIC I thought DB is the simpliest and fastest solution for that
>> task, RPC is too complicated from my point of view
>>
>>
>> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> ok Thanks!
>>> Sure I can write that, where do you need the result of it?
>>>
>>>
>>> Sebastian
>>>
>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> OK
>>>> no problem
>>>> lets remove it
>>>>
>>>> can you please write RPC call performing user count retrieving?
>>>>
>>>>
>>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> I agree however that are more comfortable way of getting RoomClients
>>>>> by RoomId might be needed.
>>>>> However this is a very different issue.
>>>>> This is no argument for moving it to the database.
>>>>> You can organize the data structure in the memory more efficiently,
>>>>> make several Lists for fast access et cetera.
>>>>> Or for example store it using EHCache. I thought also that it was our
>>>>> plan that at some point we will externalize the session vars to EHCache, so
>>>>> that you have the chance to configure the session storage size and
>>>>> externalize it to disk in case needed.
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>>
>>>>> the standard call to get a room client is not to get the roomclients
>>>>>> by its roomid.
>>>>>> The standard call to get a room client is to get the roomclient by
>>>>>> its streamid !!!
>>>>>> And this call is done for every RoomClient per sync method.
>>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>>> I thought I have tried to explain the calculation.
>>>>>>
>>>>>> I just don't understand this whole discussion, we have a single
>>>>>> requirement:
>>>>>> Calculate the list of users per room.
>>>>>> And now we need to switch a session object to the database?
>>>>>>
>>>>>> I don't see a need for a hybrid solution to have session objects
>>>>>> twice.
>>>>>> There will be multiple issues in syncing the information in the
>>>>>> session objects:
>>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>>> It will not be get simpler by your solution:
>>>>>> If the users connects as "Screensharing Client" your logic will not
>>>>>> detect it.
>>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>>> detect it.
>>>>>> So actually you will have multiple methods in the
>>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>>> the database otherwise the database object is of quite limited use.
>>>>>>
>>>>>> I really don't think splitting up that logic to database and session
>>>>>> makes things more easy.
>>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>>> ROOMATTENDEE" ;)
>>>>>> Just for having such a query we are not going to switch around a
>>>>>> session object to the database.
>>>>>> It just has too many drawbacks.
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>>>
>>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>>
>>>>>>> I still think that if code will be changed from
>>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>>             for (IConnection conn : conset) {
>>>>>>>                 if (conn != null) {
>>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>>                             .getClientByStreamId(conn
>>>>>>>                                     .getClient().getId());
>>>>>>>                     if (rcl == null) {
>>>>>>>                         // continue;
>>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>>                         // continue;
>>>>>>>                     } else {
>>>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>>>                             // do staff here
>>>>>>>                         }
>>>>>>>                     }
>>>>>>>                 }
>>>>>>>             }
>>>>>>>         }
>>>>>>>
>>>>>>>
>>>>>>> to:
>>>>>>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>>>>>>>       // do same staff here
>>>>>>> }
>>>>>>>
>>>>>>> we will have
>>>>>>> 1) only one DB call per broadcast
>>>>>>> 2) 1 loop instead 2 nested loops
>>>>>>> 3) no 3 level filtering inside second loop
>>>>>>>
>>>>>>>
>>>>>>> To implement your solution and remove RoomClient from DB, I propose
>>>>>>> the following:
>>>>>>> 1) remove RoomClient from DB
>>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>>> info while getting list of users currently in room)
>>>>>>>
>>>>>>> Is it OK?
>>>>>>>
>>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>> => userC asks for the list of rooms including the number of users.
>>>>>>>> The server side will calc the users per room. Either by calculating
>>>>>>>> the rooms locally, or by perrforming a RPC call to the connected server to
>>>>>>>> get the list of current usercount per room.
>>>>>>>> userC will only peform a single call, server might do mulitple
>>>>>>>> calls to calc the usercount, but it sends back a single answer.
>>>>>>>> So there is no multiple calls needed.
>>>>>>>> For a future iteration we might also think about a master slave
>>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>>
>>>>>>>> However for the time being I think it is acceptable, with a
>>>>>>>> scenario of 2-3 servers in the cluster such a RPC call might take 2 seconds
>>>>>>>> longer then currently, but I think that is ok for now.
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>>
>>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> Hello Sebastian,
>>>>>>>>>
>>>>>>>>> Imagine the following situation:
>>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed
>>>>>>>>> with same DB
>>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned
>>>>>>>>> to serverB) each have 10 active users in it right now
>>>>>>>>>
>>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>>>> counting connections) and roomB (no user count)
>>>>>>>>>
>>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> How do you handle rooms in general in that solution, is a single
>>>>>>>>>> room always on the same server instance.
>>>>>>>>>> Or in other words:
>>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>>> different servers?
>>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>>> You can't stream a video from server instance 1 and from instance
>>>>>>>>>> 2 at the same time.
>>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>>
>>>>>>>>>> The other point is of course you will have to write a script that
>>>>>>>>>> will collect the number of users per room from all server instances and
>>>>>>>>>> then calculate the sum of it.
>>>>>>>>>> I would collect this on the server side and then give the client
>>>>>>>>>> just the result of it. For the client it would look like a single RPC call,
>>>>>>>>>> while on server side, the server asks each instance for its usage
>>>>>>>>>> numbers/statistics.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>>>> clients.
>>>>>>>>>>>
>>>>>>>>>>> Now User enters server1 and would like to see how much users in
>>>>>>>>>>> each room.
>>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>>> regarding second one.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>>> => There are at least three alternative ways to get this number:
>>>>>>>>>>>> a) You count the number of connection of a certain scope and
>>>>>>>>>>>> then take the sum of it
>>>>>>>>>>>> This will give you the total number of connections, no matter
>>>>>>>>>>>> if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>>>>>> session
>>>>>>>>>>>> This will give you the total number of connections, no matter
>>>>>>>>>>>> if audio/video, conferencing or a screensharing connection.
>>>>>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>>> With this method you would be able to calc the exact number of
>>>>>>>>>>>> Audio/Video connection
>>>>>>>>>>>>
>>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>>
>>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in
>>>>>>>>>>>>> the DB to resolve 3)
>>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>>>>>>>> 3) To have the number of users per server instance there is
>>>>>>>>>>>>>> no need to have the RoomClient in the database.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Practically in this case you would have to iterate thorugh
>>>>>>>>>>>>>>> the connection.
>>>>>>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how many
>>>>>>>>>>>>>>> of those connection are screensharing or Audio/Video you can't tell how
>>>>>>>>>>>>>>> many users exactly there are.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB
>>>>>>>>>>>>>>>> since I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We could even store it currently in the IConnection. The
>>>>>>>>>>>>>>>>> Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the
>>>>>>>>>>>>>>>>> next 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed
>>>>>>>>>>>>>>>>>> in the future.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed
>>>>>>>>>>>>>>>>>>> that you need to get the RoomClient by its public SID. However this usage
>>>>>>>>>>>>>>>>>>> was quite limited.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use
>>>>>>>>>>>>>>>>>>> all over the application.
>>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>>>>>>> And if you iterate like described through all connection
>>>>>>>>>>>>>>>>>>> (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this
>>>>>>>>>>>>>>>>>>>> is why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>> <se...@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing
>>>>>>>>>>>>>>>>>>>>> session variables. This is simply a bad design decision that will cost a
>>>>>>>>>>>>>>>>>>>>> lot of performance in the future.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for
>>>>>>>>>>>>>>>>>>>>>> XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB
>>>>>>>>>>>>>>>>>>>>>>> is quered only once)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I
>>>>>>>>>>>>>>>>>>>>>>> think the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient
>>>>>>>>>>>>>>>>>>>>>>> hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune
>>>>>>>>>>>>>>>>>>>>>>> up openjpa cache and if it doesn't help will split RoomClient to the couple
>>>>>>>>>>>>>>>>>>>>>>> of objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine
>>>>>>>>>>>>>>>>>>>>>>>> the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if
>>>>>>>>>>>>>>>>>>>>>>>> you think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you
>>>>>>>>>>>>>>>>>>>>>>>> will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user
>>>>>>>>>>>>>>>>>>>>>>>> sessions and more.
>>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger
>>>>>>>>>>>>>>>>>>>>>>>> db actions.However I don't think having two times the RoomClient stored
>>>>>>>>>>>>>>>>>>>>>>>> (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO
>>>>>>>>>>>>>>>>>>>>>>>>>> implements OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted =
>>>>>>>>>>>>>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null)
>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms
>>>>>>>>>>>>>>>>>>>>>>>>>> implements Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room
>>>>>>>>>>>>>>>>>>>>>>>>>> = new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("createRoom", new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() !=
>>>>>>>>>>>>>>>>>>>>>>>>>> null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       , width:
>>>>>>>>>>>>>>>>>>>>>>>>>> 400
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       , width:
>>>>>>>>>>>>>>>>>>>>>>>>>> 450
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         , modal:
>>>>>>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>       <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>>       <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> </td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a =
>>>>>>>>>>>>>>>>>>>>>>>>>> new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
Memory is always faster then database.
What makes this task complex is not to have the session in the database or
memory.

Our issue is that we want to have the same information on multiple
instances.
That is basically a clusterization issue and how we will sync the data
between instances.
But I don't think that having a single database will solve anything. You
will break the whole concept of OpenJPA and other ORMs. They are all using
caching to speed up things. We just disable it now completely. Why using an
ORM if you don't use its advantages?

And of course you will still run into issues if multiple instances write to
the same database.
That simply does not work if there is no synchronization between the calls.

I would have never tried to build a single database for a clustorization
solution.
>From my point of view a Master/Slave solution would be much more desirable.
The Master => Handles the database
The Slave(s) simply are redirect targets.
I mean: What do you really want to scale ?! Database access?! NO !
Streaming is CPU/memory intensive. So what you want to scale is that the
streaming is handled by multiple instances.
So actually in my mind I never thought of having the Slave(s) write
anything to the Master database. They could have their own one. My basic
concern was to have the same File-Explorer view on all clients. That is why
I refactored the Flie-Explorer UI to use REST instead of RTMP. You could
simply switch the URL and always connect to the MASTER from all conference
rooms (while RTMP is handled from via slaves).

Sebastian


2012/10/26 Maxim Solodovnik <so...@gmail.com>

> i need Rooms.currentusers field to be filled with current users
>
> for example in the method like this:
>
> ConferenceService.getRoomsByOrganisationWithoutType
> ConferenceService.getRoomsPublic
>
> I'll add similar calls to necessary methods while implementing room lists
> on wicket.
>
> OFFTOPIC I thought DB is the simpliest and fastest solution for that task,
> RPC is too complicated from my point of view
>
>
> On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> ok Thanks!
>> Sure I can write that, where do you need the result of it?
>>
>>
>> Sebastian
>>
>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>
>>> OK
>>> no problem
>>> lets remove it
>>>
>>> can you please write RPC call performing user count retrieving?
>>>
>>>
>>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> I agree however that are more comfortable way of getting RoomClients by
>>>> RoomId might be needed.
>>>> However this is a very different issue.
>>>> This is no argument for moving it to the database.
>>>> You can organize the data structure in the memory more efficiently,
>>>> make several Lists for fast access et cetera.
>>>> Or for example store it using EHCache. I thought also that it was our
>>>> plan that at some point we will externalize the session vars to EHCache, so
>>>> that you have the chance to configure the session storage size and
>>>> externalize it to disk in case needed.
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>>
>>>> the standard call to get a room client is not to get the roomclients by
>>>>> its roomid.
>>>>> The standard call to get a room client is to get the roomclient by its
>>>>> streamid !!!
>>>>> And this call is done for every RoomClient per sync method.
>>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>>> I thought I have tried to explain the calculation.
>>>>>
>>>>> I just don't understand this whole discussion, we have a single
>>>>> requirement:
>>>>> Calculate the list of users per room.
>>>>> And now we need to switch a session object to the database?
>>>>>
>>>>> I don't see a need for a hybrid solution to have session objects twice.
>>>>> There will be multiple issues in syncing the information in the
>>>>> session objects:
>>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>>> It will not be get simpler by your solution:
>>>>> If the users connects as "Screensharing Client" your logic will not
>>>>> detect it.
>>>>> If the user connects as "Audio/Video Client" your logic will not
>>>>> detect it.
>>>>> So actually you will have multiple methods in the
>>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>>> the database otherwise the database object is of quite limited use.
>>>>>
>>>>> I really don't think splitting up that logic to database and session
>>>>> makes things more easy.
>>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>>> ROOMATTENDEE" ;)
>>>>> Just for having such a query we are not going to switch around a
>>>>> session object to the database.
>>>>> It just has too many drawbacks.
>>>>>
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>>
>>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>>
>>>>>> I still think that if code will be changed from
>>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>>             for (IConnection conn : conset) {
>>>>>>                 if (conn != null) {
>>>>>>                     RoomClient rcl = this.clientListManager
>>>>>>                             .getClientByStreamId(conn
>>>>>>                                     .getClient().getId());
>>>>>>                     if (rcl == null) {
>>>>>>                         // continue;
>>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>>                             && rcl.getIsScreenClient()) {
>>>>>>                         // continue;
>>>>>>                     } else {
>>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>>                             // do staff here
>>>>>>                         }
>>>>>>                     }
>>>>>>                 }
>>>>>>             }
>>>>>>         }
>>>>>>
>>>>>>
>>>>>> to:
>>>>>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>>>>>>       // do same staff here
>>>>>> }
>>>>>>
>>>>>> we will have
>>>>>> 1) only one DB call per broadcast
>>>>>> 2) 1 loop instead 2 nested loops
>>>>>> 3) no 3 level filtering inside second loop
>>>>>>
>>>>>>
>>>>>> To implement your solution and remove RoomClient from DB, I propose
>>>>>> the following:
>>>>>> 1) remove RoomClient from DB
>>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal
>>>>>> attendee info and will be queried only to get room clients and their basic
>>>>>> info while getting list of users currently in room)
>>>>>>
>>>>>> Is it OK?
>>>>>>
>>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> Now userC opens OM installed on serverA
>>>>>>> => userC asks for the list of rooms including the number of users.
>>>>>>> The server side will calc the users per room. Either by calculating
>>>>>>> the rooms locally, or by perrforming a RPC call to the connected server to
>>>>>>> get the list of current usercount per room.
>>>>>>> userC will only peform a single call, server might do mulitple calls
>>>>>>> to calc the usercount, but it sends back a single answer.
>>>>>>> So there is no multiple calls needed.
>>>>>>> For a future iteration we might also think about a master slave
>>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>>
>>>>>>> However for the time being I think it is acceptable, with a scenario
>>>>>>> of 2-3 servers in the cluster such a RPC call might take 2 seconds longer
>>>>>>> then currently, but I think that is ok for now.
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>>
>>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> Hello Sebastian,
>>>>>>>>
>>>>>>>> Imagine the following situation:
>>>>>>>> We have 2 servers: serverA and serverB, both have OM installed with
>>>>>>>> same DB
>>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>>>>>>>> serverB) each have 10 active users in it right now
>>>>>>>>
>>>>>>>> Now userC opens OM installed on serverA
>>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>>> counting connections) and roomB (no user count)
>>>>>>>>
>>>>>>>> performing RTMP call from client to both server seems to be
>>>>>>>> possible but complicated solution for the LZX client, but it seems to
>>>>>>>> me unacceptable for the wicket client.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> How do you handle rooms in general in that solution, is a single
>>>>>>>>> room always on the same server instance.
>>>>>>>>> Or in other words:
>>>>>>>>> Can it happens that two users are in the same room but on
>>>>>>>>> different servers?
>>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>>> You can't stream a video from server instance 1 and from instance
>>>>>>>>> 2 at the same time.
>>>>>>>>> So users of a one room are always on the same server.
>>>>>>>>> That should also make the calculation easier.
>>>>>>>>>
>>>>>>>>> The other point is of course you will have to write a script that
>>>>>>>>> will collect the number of users per room from all server instances and
>>>>>>>>> then calculate the sum of it.
>>>>>>>>> I would collect this on the server side and then give the client
>>>>>>>>> just the result of it. For the client it would look like a single RPC call,
>>>>>>>>> while on server side, the server asks each instance for its usage
>>>>>>>>> numbers/statistics.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>>> clients.
>>>>>>>>>>
>>>>>>>>>> Now User enters server1 and would like to see how much users in
>>>>>>>>>> each room.
>>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>>> regarding second one.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>>> => There are at least three alternative ways to get this number:
>>>>>>>>>>> a) You count the number of connection of a certain scope and
>>>>>>>>>>> then take the sum of it
>>>>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>>>>> session
>>>>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>>> With this method you would be able to calc the exact number of
>>>>>>>>>>> Audio/Video connection
>>>>>>>>>>>
>>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>>
>>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in
>>>>>>>>>>>> the DB to resolve 3)
>>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>>
>>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>>>>>>> 3) To have the number of users per server instance there is no
>>>>>>>>>>>>> need to have the RoomClient in the database.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>>>>>>>> connection.
>>>>>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>>>>>> This would give a rough idea. But as you don't know how many
>>>>>>>>>>>>>> of those connection are screensharing or Audio/Video you can't tell how
>>>>>>>>>>>>>> many users exactly there are.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB
>>>>>>>>>>>>>>> since I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We could even store it currently in the IConnection. The
>>>>>>>>>>>>>>>> Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the next
>>>>>>>>>>>>>>>> 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed
>>>>>>>>>>>>>>>>> in the future.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed that
>>>>>>>>>>>>>>>>>> you need to get the RoomClient by its public SID. However this usage was
>>>>>>>>>>>>>>>>>> quite limited.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use
>>>>>>>>>>>>>>>>>> all over the application.
>>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>>>>>> And if you iterate like described through all connection
>>>>>>>>>>>>>>>>>> (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you
>>>>>>>>>>>>>>>>>> speak in the video pod:
>>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will
>>>>>>>>>>>>>>>>>> flush 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this
>>>>>>>>>>>>>>>>>>> is why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But
>>>>>>>>>>>>>>>>>>> having it as DB object was the only option to have user count in the room
>>>>>>>>>>>>>>>>>>> (in case Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for
>>>>>>>>>>>>>>>>>>>>> XML export/import" is not necessary since it doesn't have @Element
>>>>>>>>>>>>>>>>>>>>> annotation
>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB
>>>>>>>>>>>>>>>>>>>>>> is quered only once)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think
>>>>>>>>>>>>>>>>>>>>>> the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient
>>>>>>>>>>>>>>>>>>>>>> hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune
>>>>>>>>>>>>>>>>>>>>>> up openjpa cache and if it doesn't help will split RoomClient to the couple
>>>>>>>>>>>>>>>>>>>>>> of objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine
>>>>>>>>>>>>>>>>>>>>>>> the current users in the room.
>>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you
>>>>>>>>>>>>>>>>>>>>>>> think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you
>>>>>>>>>>>>>>>>>>>>>>> will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions
>>>>>>>>>>>>>>>>>>>>>>> and more.
>>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger
>>>>>>>>>>>>>>>>>>>>>>> db actions.However I don't think having two times the RoomClient stored
>>>>>>>>>>>>>>>>>>>>>>> (one time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms
>>>>>>>>>>>>>>>>>>>>>>>> Entity:
>>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted =
>>>>>>>>>>>>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID
>>>>>>>>>>>>>>>>>>>>>>>>> = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room =
>>>>>>>>>>>>>>>>>>>>>>>>> new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom",
>>>>>>>>>>>>>>>>>>>>>>>>> new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() !=
>>>>>>>>>>>>>>>>>>>>>>>>> null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>>> -                                       , width:
>>>>>>>>>>>>>>>>>>>>>>>>> 400
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       , width:
>>>>>>>>>>>>>>>>>>>>>>>>> 450
>>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>>> autoOpen: false
>>>>>>>>>>>>>>>>>>>>>>>>>                                         , modal:
>>>>>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>       <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>>       <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> </td>
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> <td colspan="2" style="text-align: right"><input type="button"
>>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="save" /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a =
>>>>>>>>>>>>>>>>>>>>>>>>> new Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
i need Rooms.currentusers field to be filled with current users

for example in the method like this:

ConferenceService.getRoomsByOrganisationWithoutType
ConferenceService.getRoomsPublic

I'll add similar calls to necessary methods while implementing room lists
on wicket.

OFFTOPIC I thought DB is the simpliest and fastest solution for that task,
RPC is too complicated from my point of view

On Fri, Oct 26, 2012 at 3:03 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> ok Thanks!
> Sure I can write that, where do you need the result of it?
>
>
> Sebastian
>
> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>
>> OK
>> no problem
>> lets remove it
>>
>> can you please write RPC call performing user count retrieving?
>>
>>
>> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> I agree however that are more comfortable way of getting RoomClients by
>>> RoomId might be needed.
>>> However this is a very different issue.
>>> This is no argument for moving it to the database.
>>> You can organize the data structure in the memory more efficiently, make
>>> several Lists for fast access et cetera.
>>> Or for example store it using EHCache. I thought also that it was our
>>> plan that at some point we will externalize the session vars to EHCache, so
>>> that you have the chance to configure the session storage size and
>>> externalize it to disk in case needed.
>>>
>>> Sebastian
>>>
>>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>> the standard call to get a room client is not to get the roomclients by
>>>> its roomid.
>>>> The standard call to get a room client is to get the roomclient by its
>>>> streamid !!!
>>>> And this call is done for every RoomClient per sync method.
>>>> So if there are 100 clients in a room = 100 db calls per sync.
>>>> I thought I have tried to explain the calculation.
>>>>
>>>> I just don't understand this whole discussion, we have a single
>>>> requirement:
>>>> Calculate the list of users per room.
>>>> And now we need to switch a session object to the database?
>>>>
>>>> I don't see a need for a hybrid solution to have session objects twice.
>>>> There will be multiple issues in syncing the information in the session
>>>> objects:
>>>> A single user can create 2 or 3 RTMP connection to the server.
>>>> It will not be get simpler by your solution:
>>>> If the users connects as "Screensharing Client" your logic will not
>>>> detect it.
>>>> If the user connects as "Audio/Video Client" your logic will not detect
>>>> it.
>>>> So actually you will have multiple methods in the
>>>> ScopeApplicationAdapter where you will have to sync the session object to
>>>> the database otherwise the database object is of quite limited use.
>>>>
>>>> I really don't think splitting up that logic to database and session
>>>> makes things more easy.
>>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>>> ROOMATTENDEE" ;)
>>>> Just for having such a query we are not going to switch around a
>>>> session object to the database.
>>>> It just has too many drawbacks.
>>>>
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>>> matter by client or by server) if we already have common DB and can use it.
>>>>>
>>>>> DB can be used even if RoomClient is not DB Entity.
>>>>>
>>>>> I still think that if code will be changed from
>>>>>         for (Set<IConnection> conset : conCollection) {
>>>>>             for (IConnection conn : conset) {
>>>>>                 if (conn != null) {
>>>>>                     RoomClient rcl = this.clientListManager
>>>>>                             .getClientByStreamId(conn
>>>>>                                     .getClient().getId());
>>>>>                     if (rcl == null) {
>>>>>                         // continue;
>>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>>                             && rcl.getIsScreenClient()) {
>>>>>                         // continue;
>>>>>                     } else {
>>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>>                             // do staff here
>>>>>                         }
>>>>>                     }
>>>>>                 }
>>>>>             }
>>>>>         }
>>>>>
>>>>>
>>>>> to:
>>>>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>>>>>       // do same staff here
>>>>> }
>>>>>
>>>>> we will have
>>>>> 1) only one DB call per broadcast
>>>>> 2) 1 loop instead 2 nested loops
>>>>> 3) no 3 level filtering inside second loop
>>>>>
>>>>>
>>>>> To implement your solution and remove RoomClient from DB, I propose
>>>>> the following:
>>>>> 1) remove RoomClient from DB
>>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal attendee
>>>>> info and will be queried only to get room clients and their basic info
>>>>> while getting list of users currently in room)
>>>>>
>>>>> Is it OK?
>>>>>
>>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> Now userC opens OM installed on serverA
>>>>>> => userC asks for the list of rooms including the number of users.
>>>>>> The server side will calc the users per room. Either by calculating
>>>>>> the rooms locally, or by perrforming a RPC call to the connected server to
>>>>>> get the list of current usercount per room.
>>>>>> userC will only peform a single call, server might do mulitple calls
>>>>>> to calc the usercount, but it sends back a single answer.
>>>>>> So there is no multiple calls needed.
>>>>>> For a future iteration we might also think about a master slave
>>>>>> principle where the slave always automatically pushes current usercount to
>>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>>
>>>>>> However for the time being I think it is acceptable, with a scenario
>>>>>> of 2-3 servers in the cluster such a RPC call might take 2 seconds longer
>>>>>> then currently, but I think that is ok for now.
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>>
>>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> Hello Sebastian,
>>>>>>>
>>>>>>> Imagine the following situation:
>>>>>>> We have 2 servers: serverA and serverB, both have OM installed with
>>>>>>> same DB
>>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>>>>>>> serverB) each have 10 active users in it right now
>>>>>>>
>>>>>>> Now userC opens OM installed on serverA
>>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>>> counting connections) and roomB (no user count)
>>>>>>>
>>>>>>> performing RTMP call from client to both server seems to be possible
>>>>>>> but complicated solution for the LZX client, but it seems to
>>>>>>> me unacceptable for the wicket client.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> How do you handle rooms in general in that solution, is a single
>>>>>>>> room always on the same server instance.
>>>>>>>> Or in other words:
>>>>>>>> Can it happens that two users are in the same room but on different
>>>>>>>> servers?
>>>>>>>> Cause from my point of view that is impossible.
>>>>>>>> You can't stream a video from server instance 1 and from instance 2
>>>>>>>> at the same time.
>>>>>>>> So users of a one room are always on the same server.
>>>>>>>> That should also make the calculation easier.
>>>>>>>>
>>>>>>>> The other point is of course you will have to write a script that
>>>>>>>> will collect the number of users per room from all server instances and
>>>>>>>> then calculate the sum of it.
>>>>>>>> I would collect this on the server side and then give the client
>>>>>>>> just the result of it. For the client it would look like a single RPC call,
>>>>>>>> while on server side, the server asks each instance for its usage
>>>>>>>> numbers/statistics.
>>>>>>>>
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>>> clients.
>>>>>>>>>
>>>>>>>>> Now User enters server1 and would like to see how much users in
>>>>>>>>> each room.
>>>>>>>>> But it is impossible since server1 only have
>>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>>> regarding second one.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>>> => There are at least three alternative ways to get this number:
>>>>>>>>>> a) You count the number of connection of a certain scope and then
>>>>>>>>>> take the sum of it
>>>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>>>> session
>>>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>>> With this method you would be able to calc the exact number of
>>>>>>>>>> Audio/Video connection
>>>>>>>>>>
>>>>>>>>>> Which of those would fit yours?
>>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>>
>>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in
>>>>>>>>>>> the DB to resolve 3)
>>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>>
>>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>>
>>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>>>>>> 3) To have the number of users per server instance there is no
>>>>>>>>>>>> need to have the RoomClient in the database.
>>>>>>>>>>>>
>>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>>>>>>> connection.
>>>>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>>>>> This would give a rough idea. But as you don't know how many
>>>>>>>>>>>>> of those connection are screensharing or Audio/Video you can't tell how
>>>>>>>>>>>>> many users exactly there are.
>>>>>>>>>>>>>
>>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB
>>>>>>>>>>>>>> since I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We could even store it currently in the IConnection. The
>>>>>>>>>>>>>>> Red5 framework has the similar mechanism like the static Map that I've
>>>>>>>>>>>>>>> build.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the next
>>>>>>>>>>>>>>> 6 months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in
>>>>>>>>>>>>>>>> the future.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed that
>>>>>>>>>>>>>>>>> you need to get the RoomClient by its public SID. However this usage was
>>>>>>>>>>>>>>>>> quite limited.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use all
>>>>>>>>>>>>>>>>> over the application.
>>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>>>>> And if you iterate like described through all connection
>>>>>>>>>>>>>>>>> (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you speak
>>>>>>>>>>>>>>>>> in the video pod:
>>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will flush
>>>>>>>>>>>>>>>>> 10 mabye 10 times per second.
>>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users
>>>>>>>>>>>>>>>>> watching. Now scale that up to 1000 concurrent rooms with  4x4 meetings
>>>>>>>>>>>>>>>>> where every user has micro turned on ?! Should we calc the number of
>>>>>>>>>>>>>>>>> database queries really?!
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is
>>>>>>>>>>>>>>>>>> why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having
>>>>>>>>>>>>>>>>>> it as DB object was the only option to have user count in the room (in case
>>>>>>>>>>>>>>>>>> Rooms are on the different servers).
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single
>>>>>>>>>>>>>>>>>>> HashMap.
>>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database
>>>>>>>>>>>>>>>>>>> query. The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB
>>>>>>>>>>>>>>>>>>>>> is quered only once)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think
>>>>>>>>>>>>>>>>>>>>> the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient
>>>>>>>>>>>>>>>>>>>>> hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune
>>>>>>>>>>>>>>>>>>>>> up openjpa cache and if it doesn't help will split RoomClient to the couple
>>>>>>>>>>>>>>>>>>>>> of objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine
>>>>>>>>>>>>>>>>>>>>>> the current users in the room.
>>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you
>>>>>>>>>>>>>>>>>>>>>> think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you
>>>>>>>>>>>>>>>>>>>>>> will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions
>>>>>>>>>>>>>>>>>>>>>> and more.
>>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating
>>>>>>>>>>>>>>>>>>>>>>> through the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from
>>>>>>>>>>>>>>>>>>>>>>>> Rooms r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and
>>>>>>>>>>>>>>>>>>>>>>>> r.deleted= false ORDER BY r.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms>
>>>>>>>>>>>>>>>>>>>>>>>> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>>> em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted =
>>>>>>>>>>>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>>> Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID
>>>>>>>>>>>>>>>>>>>>>>>> = -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm
>>>>>>>>>>>>>>>>>>>>>>>> extends Form<A
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room =
>>>>>>>>>>>>>>>>>>>>>>>> new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom",
>>>>>>>>>>>>>>>>>>>>>>>> new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() !=
>>>>>>>>>>>>>>>>>>>>>>>> null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>>                                         ,
>>>>>>>>>>>>>>>>>>>>>>>> resizable: true
>>>>>>>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>>>>>>>                                         , autoOpen:
>>>>>>>>>>>>>>>>>>>>>>>> false
>>>>>>>>>>>>>>>>>>>>>>>>                                         , modal:
>>>>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>     <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>>     <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>> </td>
>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
ok Thanks!
Sure I can write that, where do you need the result of it?

Sebastian

2012/10/26 Maxim Solodovnik <so...@gmail.com>

> OK
> no problem
> lets remove it
>
> can you please write RPC call performing user count retrieving?
>
>
> On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> I agree however that are more comfortable way of getting RoomClients by
>> RoomId might be needed.
>> However this is a very different issue.
>> This is no argument for moving it to the database.
>> You can organize the data structure in the memory more efficiently, make
>> several Lists for fast access et cetera.
>> Or for example store it using EHCache. I thought also that it was our
>> plan that at some point we will externalize the session vars to EHCache, so
>> that you have the chance to configure the session storage size and
>> externalize it to disk in case needed.
>>
>> Sebastian
>>
>> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>>
>> the standard call to get a room client is not to get the roomclients by
>>> its roomid.
>>> The standard call to get a room client is to get the roomclient by its
>>> streamid !!!
>>> And this call is done for every RoomClient per sync method.
>>> So if there are 100 clients in a room = 100 db calls per sync.
>>> I thought I have tried to explain the calculation.
>>>
>>> I just don't understand this whole discussion, we have a single
>>> requirement:
>>> Calculate the list of users per room.
>>> And now we need to switch a session object to the database?
>>>
>>> I don't see a need for a hybrid solution to have session objects twice.
>>> There will be multiple issues in syncing the information in the session
>>> objects:
>>> A single user can create 2 or 3 RTMP connection to the server.
>>> It will not be get simpler by your solution:
>>> If the users connects as "Screensharing Client" your logic will not
>>> detect it.
>>> If the user connects as "Audio/Video Client" your logic will not detect
>>> it.
>>> So actually you will have multiple methods in the
>>> ScopeApplicationAdapter where you will have to sync the session object to
>>> the database otherwise the database object is of quite limited use.
>>>
>>> I really don't think splitting up that logic to database and session
>>> makes things more easy.
>>> All you want is to use a query like "SELECT ROOM JOIN FETCH
>>> ROOMATTENDEE" ;)
>>> Just for having such a query we are not going to switch around a session
>>> object to the database.
>>> It just has too many drawbacks.
>>>
>>>
>>> Sebastian
>>>
>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> I'm afraid I never can get why do we need to perform RPC call (no
>>>> matter by client or by server) if we already have common DB and can use it.
>>>>
>>>> DB can be used even if RoomClient is not DB Entity.
>>>>
>>>> I still think that if code will be changed from
>>>>         for (Set<IConnection> conset : conCollection) {
>>>>             for (IConnection conn : conset) {
>>>>                 if (conn != null) {
>>>>                     RoomClient rcl = this.clientListManager
>>>>                             .getClientByStreamId(conn
>>>>                                     .getClient().getId());
>>>>                     if (rcl == null) {
>>>>                         // continue;
>>>>                     } else if (rcl.getIsScreenClient() != null
>>>>                             && rcl.getIsScreenClient()) {
>>>>                         // continue;
>>>>                     } else {
>>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>>                             // do staff here
>>>>                         }
>>>>                     }
>>>>                 }
>>>>             }
>>>>         }
>>>>
>>>>
>>>> to:
>>>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>>>>       // do same staff here
>>>> }
>>>>
>>>> we will have
>>>> 1) only one DB call per broadcast
>>>> 2) 1 loop instead 2 nested loops
>>>> 3) no 3 level filtering inside second loop
>>>>
>>>>
>>>> To implement your solution and remove RoomClient from DB, I propose the
>>>> following:
>>>> 1) remove RoomClient from DB
>>>> 2) add RoomAttendee Entity to the DB (it will contain minimal attendee
>>>> info and will be queried only to get room clients and their basic info
>>>> while getting list of users currently in room)
>>>>
>>>> Is it OK?
>>>>
>>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> Now userC opens OM installed on serverA
>>>>> => userC asks for the list of rooms including the number of users.
>>>>> The server side will calc the users per room. Either by calculating
>>>>> the rooms locally, or by perrforming a RPC call to the connected server to
>>>>> get the list of current usercount per room.
>>>>> userC will only peform a single call, server might do mulitple calls
>>>>> to calc the usercount, but it sends back a single answer.
>>>>> So there is no multiple calls needed.
>>>>> For a future iteration we might also think about a master slave
>>>>> principle where the slave always automatically pushes current usercount to
>>>>> the master, so there is no need for the master to ask for the usercount.
>>>>>
>>>>> However for the time being I think it is acceptable, with a scenario
>>>>> of 2-3 servers in the cluster such a RPC call might take 2 seconds longer
>>>>> then currently, but I think that is ok for now.
>>>>>
>>>>> Sebastian
>>>>>
>>>>>
>>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> Hello Sebastian,
>>>>>>
>>>>>> Imagine the following situation:
>>>>>> We have 2 servers: serverA and serverB, both have OM installed with
>>>>>> same DB
>>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>>>>>> serverB) each have 10 active users in it right now
>>>>>>
>>>>>> Now userC opens OM installed on serverA
>>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>>> counting connections) and roomB (no user count)
>>>>>>
>>>>>> performing RTMP call from client to both server seems to be possible
>>>>>> but complicated solution for the LZX client, but it seems to
>>>>>> me unacceptable for the wicket client.
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> How do you handle rooms in general in that solution, is a single
>>>>>>> room always on the same server instance.
>>>>>>> Or in other words:
>>>>>>> Can it happens that two users are in the same room but on different
>>>>>>> servers?
>>>>>>> Cause from my point of view that is impossible.
>>>>>>> You can't stream a video from server instance 1 and from instance 2
>>>>>>> at the same time.
>>>>>>> So users of a one room are always on the same server.
>>>>>>> That should also make the calculation easier.
>>>>>>>
>>>>>>> The other point is of course you will have to write a script that
>>>>>>> will collect the number of users per room from all server instances and
>>>>>>> then calculate the sum of it.
>>>>>>> I would collect this on the server side and then give the client
>>>>>>> just the result of it. For the client it would look like a single RPC call,
>>>>>>> while on server side, the server asks each instance for its usage
>>>>>>> numbers/statistics.
>>>>>>>
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>>> clients.
>>>>>>>>
>>>>>>>> Now User enters server1 and would like to see how much users in
>>>>>>>> each room.
>>>>>>>> But it is impossible since server1 only have
>>>>>>>> connections/roomClients only for 1 server, and have no information
>>>>>>>> regarding second one.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>>> => There are at least three alternative ways to get this number:
>>>>>>>>> a) You count the number of connection of a certain scope and then
>>>>>>>>> take the sum of it
>>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>>> session
>>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>>> With this method you would be able to calc the exact number of
>>>>>>>>> Audio/Video connection
>>>>>>>>>
>>>>>>>>> Which of those would fit yours?
>>>>>>>>> Or did I misunderstood something?
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> Hello Sebastian,
>>>>>>>>>>
>>>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in the
>>>>>>>>>> DB to resolve 3)
>>>>>>>>>> This can be done without performance degradation.
>>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>>
>>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>>
>>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>>>>> 3) To have the number of users per server instance there is no
>>>>>>>>>>> need to have the RoomClient in the database.
>>>>>>>>>>>
>>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>>>>>> connection.
>>>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>>>> This would give a rough idea. But as you don't know how many of
>>>>>>>>>>>> those connection are screensharing or Audio/Video you can't tell how many
>>>>>>>>>>>> users exactly there are.
>>>>>>>>>>>>
>>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB
>>>>>>>>>>>>> since I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> It is no option to stay with it, how can we offer
>>>>>>>>>>>>>> OpenMeetings to be scalable to 1000 concurrent users? We would have to
>>>>>>>>>>>>>> limit it to 250. Also it would become mandatory to have the database server
>>>>>>>>>>>>>> on the same machine as the red5 server. Otherwise you have performance
>>>>>>>>>>>>>> bottlenecks. Can you imagine what kind of negative public feedback we will
>>>>>>>>>>>>>> have if every question about performance of red5 is answered with: Did you
>>>>>>>>>>>>>> install db server on another instance of your network?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in
>>>>>>>>>>>>>>> the future.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>>> There are _some_ implementations where it was needed that
>>>>>>>>>>>>>>>> you need to get the RoomClient by its public SID. However this usage was
>>>>>>>>>>>>>>>> quite limited.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was
>>>>>>>>>>>>>>>> obtained from the IConnection of each stream.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use all
>>>>>>>>>>>>>>>> over the application.
>>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>>>> And if you iterate like described through all connection
>>>>>>>>>>>>>>>> (like it is in EVERY snyc method)
>>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>>> Think about the green dot that blinks every time you speak
>>>>>>>>>>>>>>>> in the video pod:
>>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will flush
>>>>>>>>>>>>>>>> 10 mabye 10 times per second.
>>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching.
>>>>>>>>>>>>>>>> Now scale that up to 1000 concurrent rooms with  4x4 meetings where every
>>>>>>>>>>>>>>>> user has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>>>>>>>> really?!
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is
>>>>>>>>>>>>>>>>> why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having
>>>>>>>>>>>>>>>>> it as DB object was the only option to have user count in the room (in case
>>>>>>>>>>>>>>>>> Rooms are on the different servers).
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database query.
>>>>>>>>>>>>>>>>>> The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think
>>>>>>>>>>>>>>>>>>>> the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient
>>>>>>>>>>>>>>>>>>>> hash map to get subset required.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these
>>>>>>>>>>>>>>>>>>>> changes are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you
>>>>>>>>>>>>>>>>>>>>> think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you
>>>>>>>>>>>>>>>>>>>>> will create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions
>>>>>>>>>>>>>>>>>>>>> and more.
>>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating through
>>>>>>>>>>>>>>>>>>>>>> the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms
>>>>>>>>>>>>>>>>>>>>>>> r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted=
>>>>>>>>>>>>>>>>>>>>>>> false ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted =
>>>>>>>>>>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import
>>>>>>>>>>>>>>>>>>>>>>> javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment>
>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>>> Form<A
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room =
>>>>>>>>>>>>>>>>>>>>>>> new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom",
>>>>>>>>>>>>>>>>>>>>>>> new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() !=
>>>>>>>>>>>>>>>>>>>>>>> null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>>                                         , resizable:
>>>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>>>>>>                                         , autoOpen:
>>>>>>>>>>>>>>>>>>>>>>> false
>>>>>>>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>     <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>>     <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
OK
no problem
lets remove it

can you please write RPC call performing user count retrieving?

On Fri, Oct 26, 2012 at 2:55 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> I agree however that are more comfortable way of getting RoomClients by
> RoomId might be needed.
> However this is a very different issue.
> This is no argument for moving it to the database.
> You can organize the data structure in the memory more efficiently, make
> several Lists for fast access et cetera.
> Or for example store it using EHCache. I thought also that it was our plan
> that at some point we will externalize the session vars to EHCache, so that
> you have the chance to configure the session storage size and externalize
> it to disk in case needed.
>
> Sebastian
>
> 2012/10/26 seba.wagner@gmail.com <se...@gmail.com>
>
> the standard call to get a room client is not to get the roomclients by
>> its roomid.
>> The standard call to get a room client is to get the roomclient by its
>> streamid !!!
>> And this call is done for every RoomClient per sync method.
>> So if there are 100 clients in a room = 100 db calls per sync.
>> I thought I have tried to explain the calculation.
>>
>> I just don't understand this whole discussion, we have a single
>> requirement:
>> Calculate the list of users per room.
>> And now we need to switch a session object to the database?
>>
>> I don't see a need for a hybrid solution to have session objects twice.
>> There will be multiple issues in syncing the information in the session
>> objects:
>> A single user can create 2 or 3 RTMP connection to the server.
>> It will not be get simpler by your solution:
>> If the users connects as "Screensharing Client" your logic will not
>> detect it.
>> If the user connects as "Audio/Video Client" your logic will not detect
>> it.
>> So actually you will have multiple methods in the ScopeApplicationAdapter
>> where you will have to sync the session object to the database otherwise
>> the database object is of quite limited use.
>>
>> I really don't think splitting up that logic to database and session
>> makes things more easy.
>> All you want is to use a query like "SELECT ROOM JOIN FETCH ROOMATTENDEE"
>> ;)
>> Just for having such a query we are not going to switch around a session
>> object to the database.
>> It just has too many drawbacks.
>>
>>
>> Sebastian
>>
>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>
>>> I'm afraid I never can get why do we need to perform RPC call (no matter
>>> by client or by server) if we already have common DB and can use it.
>>>
>>> DB can be used even if RoomClient is not DB Entity.
>>>
>>> I still think that if code will be changed from
>>>         for (Set<IConnection> conset : conCollection) {
>>>             for (IConnection conn : conset) {
>>>                 if (conn != null) {
>>>                     RoomClient rcl = this.clientListManager
>>>                             .getClientByStreamId(conn
>>>                                     .getClient().getId());
>>>                     if (rcl == null) {
>>>                         // continue;
>>>                     } else if (rcl.getIsScreenClient() != null
>>>                             && rcl.getIsScreenClient()) {
>>>                         // continue;
>>>                     } else {
>>>                         if (!streamid.equals(rcl.getStreamid())) {
>>>                             // do staff here
>>>                         }
>>>                     }
>>>                 }
>>>             }
>>>         }
>>>
>>>
>>> to:
>>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>>>       // do same staff here
>>> }
>>>
>>> we will have
>>> 1) only one DB call per broadcast
>>> 2) 1 loop instead 2 nested loops
>>> 3) no 3 level filtering inside second loop
>>>
>>>
>>> To implement your solution and remove RoomClient from DB, I propose the
>>> following:
>>> 1) remove RoomClient from DB
>>> 2) add RoomAttendee Entity to the DB (it will contain minimal attendee
>>> info and will be queried only to get room clients and their basic info
>>> while getting list of users currently in room)
>>>
>>> Is it OK?
>>>
>>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> Now userC opens OM installed on serverA
>>>> => userC asks for the list of rooms including the number of users.
>>>> The server side will calc the users per room. Either by calculating the
>>>> rooms locally, or by perrforming a RPC call to the connected server to get
>>>> the list of current usercount per room.
>>>> userC will only peform a single call, server might do mulitple calls to
>>>> calc the usercount, but it sends back a single answer.
>>>> So there is no multiple calls needed.
>>>> For a future iteration we might also think about a master slave
>>>> principle where the slave always automatically pushes current usercount to
>>>> the master, so there is no need for the master to ask for the usercount.
>>>>
>>>> However for the time being I think it is acceptable, with a scenario of
>>>> 2-3 servers in the cluster such a RPC call might take 2 seconds longer then
>>>> currently, but I think that is ok for now.
>>>>
>>>> Sebastian
>>>>
>>>>
>>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> Hello Sebastian,
>>>>>
>>>>> Imagine the following situation:
>>>>> We have 2 servers: serverA and serverB, both have OM installed with
>>>>> same DB
>>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>>>>> serverB) each have 10 active users in it right now
>>>>>
>>>>> Now userC opens OM installed on serverA
>>>>> In the list of rooms he can see roomA (user count can be get by
>>>>> counting connections) and roomB (no user count)
>>>>>
>>>>> performing RTMP call from client to both server seems to be possible
>>>>> but complicated solution for the LZX client, but it seems to
>>>>> me unacceptable for the wicket client.
>>>>>
>>>>>
>>>>>
>>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> How do you handle rooms in general in that solution, is a single room
>>>>>> always on the same server instance.
>>>>>> Or in other words:
>>>>>> Can it happens that two users are in the same room but on different
>>>>>> servers?
>>>>>> Cause from my point of view that is impossible.
>>>>>> You can't stream a video from server instance 1 and from instance 2
>>>>>> at the same time.
>>>>>> So users of a one room are always on the same server.
>>>>>> That should also make the calculation easier.
>>>>>>
>>>>>> The other point is of course you will have to write a script that
>>>>>> will collect the number of users per room from all server instances and
>>>>>> then calculate the sum of it.
>>>>>> I would collect this on the server side and then give the client just
>>>>>> the result of it. For the client it would look like a single RPC call,
>>>>>> while on server side, the server asks each instance for its usage
>>>>>> numbers/statistics.
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> If there is only 1 server - all your solutions will work.
>>>>>>> But imaging we have 2 servers. Each have its own room full of
>>>>>>> clients.
>>>>>>>
>>>>>>> Now User enters server1 and would like to see how much users in each
>>>>>>> room.
>>>>>>> But it is impossible since server1 only have connections/roomClients
>>>>>>> only for 1 server, and have no information regarding second one.
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>>> => There are at least three alternative ways to get this number:
>>>>>>>> a) You count the number of connection of a certain scope and then
>>>>>>>> take the sum of it
>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>> b) You count the total number of RoomClients from the current
>>>>>>>> session
>>>>>>>> This will give you the total number of connections, no matter if
>>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>>> Audio/Video client or a Screensharing client
>>>>>>>> With this method you would be able to calc the exact number of
>>>>>>>> Audio/Video connection
>>>>>>>>
>>>>>>>> Which of those would fit yours?
>>>>>>>> Or did I misunderstood something?
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>>
>>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> Hello Sebastian,
>>>>>>>>>
>>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in the
>>>>>>>>> DB to resolve 3)
>>>>>>>>> This can be done without performance degradation.
>>>>>>>>> I see no other way to get the number of users.
>>>>>>>>>
>>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>>
>>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>>>> 3) To have the number of users per server instance there is no
>>>>>>>>>> need to have the RoomClient in the database.
>>>>>>>>>>
>>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>
>>>>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>>>>> connection.
>>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>>> This would give a rough idea. But as you don't know how many of
>>>>>>>>>>> those connection are screensharing or Audio/Video you can't tell how many
>>>>>>>>>>> users exactly there are.
>>>>>>>>>>>
>>>>>>>>>>> If you want to share this information with others I would
>>>>>>>>>>> suggest you simply add a SOAP/REST call and in that sense query the number
>>>>>>>>>>> of users via a HTTP call.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB since
>>>>>>>>>>>> I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>>>>>>
>>>>>>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>>
>>>>>>>>>>>>> It is no option to stay with it, how can we offer OpenMeetings
>>>>>>>>>>>>> to be scalable to 1000 concurrent users? We would have to limit it to 250.
>>>>>>>>>>>>> Also it would become mandatory to have the database server on the same
>>>>>>>>>>>>> machine as the red5 server. Otherwise you have performance bottlenecks. Can
>>>>>>>>>>>>> you imagine what kind of negative public feedback we will have if every
>>>>>>>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>>>>>>>> server on another instance of your network?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>>
>>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in
>>>>>>>>>>>>>> the future.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>>> There are _some_ implementations where it was needed that
>>>>>>>>>>>>>>> you need to get the RoomClient by its public SID. However this usage was
>>>>>>>>>>>>>>> quite limited.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was obtained
>>>>>>>>>>>>>>> from the IConnection of each stream.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use all
>>>>>>>>>>>>>>> over the application.
>>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>>> And if you iterate like described through all connection
>>>>>>>>>>>>>>> (like it is in EVERY snyc method)
>>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>>> Think about the green dot that blinks every time you speak
>>>>>>>>>>>>>>> in the video pod:
>>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will flush
>>>>>>>>>>>>>>> 10 mabye 10 times per second.
>>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching.
>>>>>>>>>>>>>>> Now scale that up to 1000 concurrent rooms with  4x4 meetings where every
>>>>>>>>>>>>>>> user has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>>>>>>> really?!
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is
>>>>>>>>>>>>>>>> why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having
>>>>>>>>>>>>>>>> it as DB object was the only option to have user count in the room (in case
>>>>>>>>>>>>>>>> Rooms are on the different servers).
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>>> I hope everything except audio and video will move to
>>>>>>>>>>>>>>>> Wicket :)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>>> and now this single line is replaced by a Database query.
>>>>>>>>>>>>>>>>> The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think
>>>>>>>>>>>>>>>>>>> the current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash
>>>>>>>>>>>>>>>>>>> map to get subset required.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these changes
>>>>>>>>>>>>>>>>>>> are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you
>>>>>>>>>>>>>>>>>>>> think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions
>>>>>>>>>>>>>>>>>>>> and more.
>>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it
>>>>>>>>>>>>>>>>>>>> should stay in the session.
>>>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>> >
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating through
>>>>>>>>>>>>>>>>>>>>> the Red5 Connections.
>>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML
>>>>>>>>>>>>>>>>>>>>> export/import. So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms
>>>>>>>>>>>>>>>>>>>>>> r LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted=
>>>>>>>>>>>>>>>>>>>>>> false ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false
>>>>>>>>>>>>>>>>>>>>>> "
>>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long
>>>>>>>>>>>>>>>>>>>>>> userId) {
>>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>>> Form<A
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room =
>>>>>>>>>>>>>>>>>>>>>> new DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom",
>>>>>>>>>>>>>>>>>>>>>> new PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() !=
>>>>>>>>>>>>>>>>>>>>>> null && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> closeOnEscape: true
>>>>>>>>>>>>>>>>>>>>>>                                         , resizable:
>>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>>>>>                                         , autoOpen:
>>>>>>>>>>>>>>>>>>>>>> false
>>>>>>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>   <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>>   <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel
>>>>>>>>>>>>>>>>>>>>>> extends UserP
>>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> +                               if
>>>>>>>>>>>>>>>>>>>>>> (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
I agree however that are more comfortable way of getting RoomClients by
RoomId might be needed.
However this is a very different issue.
This is no argument for moving it to the database.
You can organize the data structure in the memory more efficiently, make
several Lists for fast access et cetera.
Or for example store it using EHCache. I thought also that it was our plan
that at some point we will externalize the session vars to EHCache, so that
you have the chance to configure the session storage size and externalize
it to disk in case needed.

Sebastian

2012/10/26 seba.wagner@gmail.com <se...@gmail.com>

> the standard call to get a room client is not to get the roomclients by
> its roomid.
> The standard call to get a room client is to get the roomclient by its
> streamid !!!
> And this call is done for every RoomClient per sync method.
> So if there are 100 clients in a room = 100 db calls per sync.
> I thought I have tried to explain the calculation.
>
> I just don't understand this whole discussion, we have a single
> requirement:
> Calculate the list of users per room.
> And now we need to switch a session object to the database?
>
> I don't see a need for a hybrid solution to have session objects twice.
> There will be multiple issues in syncing the information in the session
> objects:
> A single user can create 2 or 3 RTMP connection to the server.
> It will not be get simpler by your solution:
> If the users connects as "Screensharing Client" your logic will not detect
> it.
> If the user connects as "Audio/Video Client" your logic will not detect it.
> So actually you will have multiple methods in the ScopeApplicationAdapter
> where you will have to sync the session object to the database otherwise
> the database object is of quite limited use.
>
> I really don't think splitting up that logic to database and session makes
> things more easy.
> All you want is to use a query like "SELECT ROOM JOIN FETCH ROOMATTENDEE"
> ;)
> Just for having such a query we are not going to switch around a session
> object to the database.
> It just has too many drawbacks.
>
>
> Sebastian
>
> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>
>> I'm afraid I never can get why do we need to perform RPC call (no matter
>> by client or by server) if we already have common DB and can use it.
>>
>> DB can be used even if RoomClient is not DB Entity.
>>
>> I still think that if code will be changed from
>>         for (Set<IConnection> conset : conCollection) {
>>             for (IConnection conn : conset) {
>>                 if (conn != null) {
>>                     RoomClient rcl = this.clientListManager
>>                             .getClientByStreamId(conn
>>                                     .getClient().getId());
>>                     if (rcl == null) {
>>                         // continue;
>>                     } else if (rcl.getIsScreenClient() != null
>>                             && rcl.getIsScreenClient()) {
>>                         // continue;
>>                     } else {
>>                         if (!streamid.equals(rcl.getStreamid())) {
>>                             // do staff here
>>                         }
>>                     }
>>                 }
>>             }
>>         }
>>
>>
>> to:
>> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>>       // do same staff here
>> }
>>
>> we will have
>> 1) only one DB call per broadcast
>> 2) 1 loop instead 2 nested loops
>> 3) no 3 level filtering inside second loop
>>
>>
>> To implement your solution and remove RoomClient from DB, I propose the
>> following:
>> 1) remove RoomClient from DB
>> 2) add RoomAttendee Entity to the DB (it will contain minimal attendee
>> info and will be queried only to get room clients and their basic info
>> while getting list of users currently in room)
>>
>> Is it OK?
>>
>> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> Now userC opens OM installed on serverA
>>> => userC asks for the list of rooms including the number of users.
>>> The server side will calc the users per room. Either by calculating the
>>> rooms locally, or by perrforming a RPC call to the connected server to get
>>> the list of current usercount per room.
>>> userC will only peform a single call, server might do mulitple calls to
>>> calc the usercount, but it sends back a single answer.
>>> So there is no multiple calls needed.
>>> For a future iteration we might also think about a master slave
>>> principle where the slave always automatically pushes current usercount to
>>> the master, so there is no need for the master to ask for the usercount.
>>>
>>> However for the time being I think it is acceptable, with a scenario of
>>> 2-3 servers in the cluster such a RPC call might take 2 seconds longer then
>>> currently, but I think that is ok for now.
>>>
>>> Sebastian
>>>
>>>
>>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> Hello Sebastian,
>>>>
>>>> Imagine the following situation:
>>>> We have 2 servers: serverA and serverB, both have OM installed with
>>>> same DB
>>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>>>> serverB) each have 10 active users in it right now
>>>>
>>>> Now userC opens OM installed on serverA
>>>> In the list of rooms he can see roomA (user count can be get by
>>>> counting connections) and roomB (no user count)
>>>>
>>>> performing RTMP call from client to both server seems to be possible
>>>> but complicated solution for the LZX client, but it seems to
>>>> me unacceptable for the wicket client.
>>>>
>>>>
>>>>
>>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> How do you handle rooms in general in that solution, is a single room
>>>>> always on the same server instance.
>>>>> Or in other words:
>>>>> Can it happens that two users are in the same room but on different
>>>>> servers?
>>>>> Cause from my point of view that is impossible.
>>>>> You can't stream a video from server instance 1 and from instance 2 at
>>>>> the same time.
>>>>> So users of a one room are always on the same server.
>>>>> That should also make the calculation easier.
>>>>>
>>>>> The other point is of course you will have to write a script that will
>>>>> collect the number of users per room from all server instances and then
>>>>> calculate the sum of it.
>>>>> I would collect this on the server side and then give the client just
>>>>> the result of it. For the client it would look like a single RPC call,
>>>>> while on server side, the server asks each instance for its usage
>>>>> numbers/statistics.
>>>>>
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> If there is only 1 server - all your solutions will work.
>>>>>> But imaging we have 2 servers. Each have its own room full of clients.
>>>>>>
>>>>>> Now User enters server1 and would like to see how much users in each
>>>>>> room.
>>>>>> But it is impossible since server1 only have connections/roomClients
>>>>>> only for 1 server, and have no information regarding second one.
>>>>>>
>>>>>>
>>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> *I see no other way to get the number of users (per server)*
>>>>>>> => There are at least three alternative ways to get this number:
>>>>>>> a) You count the number of connection of a certain scope and then
>>>>>>> take the sum of it
>>>>>>> This will give you the total number of connections, no matter if
>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>> b) You count the total number of RoomClients from the current session
>>>>>>> This will give you the total number of connections, no matter if
>>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>>> c) You count the total number of RoomClients from the current
>>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>>> Audio/Video client or a Screensharing client
>>>>>>> With this method you would be able to calc the exact number of
>>>>>>> Audio/Video connection
>>>>>>>
>>>>>>> Which of those would fit yours?
>>>>>>> Or did I misunderstood something?
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>>
>>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> Hello Sebastian,
>>>>>>>>
>>>>>>>> I'm afraid we need something like "lightweight RoomClient" in the
>>>>>>>> DB to resolve 3)
>>>>>>>> This can be done without performance degradation.
>>>>>>>> I see no other way to get the number of users.
>>>>>>>>
>>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> So will we find a consens here? :)
>>>>>>>>>
>>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>>> 3) To have the number of users per server instance there is no
>>>>>>>>> need to have the RoomClient in the database.
>>>>>>>>>
>>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>
>>>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>>>> connection.
>>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>>> This would give a rough idea. But as you don't know how many of
>>>>>>>>>> those connection are screensharing or Audio/Video you can't tell how many
>>>>>>>>>> users exactly there are.
>>>>>>>>>>
>>>>>>>>>> If you want to share this information with others I would suggest
>>>>>>>>>> you simply add a SOAP/REST call and in that sense query the number of users
>>>>>>>>>> via a HTTP call.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> If I remember correctly I have added RoomClient to the DB since
>>>>>>>>>>> I need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>>>>>
>>>>>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>>
>>>>>>>>>>>> It is no option to stay with it, how can we offer OpenMeetings
>>>>>>>>>>>> to be scalable to 1000 concurrent users? We would have to limit it to 250.
>>>>>>>>>>>> Also it would become mandatory to have the database server on the same
>>>>>>>>>>>> machine as the red5 server. Otherwise you have performance bottlenecks. Can
>>>>>>>>>>>> you imagine what kind of negative public feedback we will have if every
>>>>>>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>>>>>>> server on another instance of your network?
>>>>>>>>>>>>
>>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary
>>>>>>>>>>>> solution. We can't sell this product like that and claim to have 1000 user
>>>>>>>>>>>> sessions per server unit.
>>>>>>>>>>>>
>>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in
>>>>>>>>>>>>> the future.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>>> There are _some_ implementations where it was needed that you
>>>>>>>>>>>>>> need to get the RoomClient by its public SID. However this usage was quite
>>>>>>>>>>>>>> limited.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>>> The maps key was the streamid. And the streamid was obtained
>>>>>>>>>>>>>> from the IConnection of each stream.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>>> Line 118, that was the function that was mainly in use all
>>>>>>>>>>>>>> over the application.
>>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>>> And if you iterate like described through all connection
>>>>>>>>>>>>>> (like it is in EVERY snyc method)
>>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>>> Think about the green dot that blinks every time you speak in
>>>>>>>>>>>>>> the video pod:
>>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>>> If you have a quite good and sensitive micro it will flush 10
>>>>>>>>>>>>>> mabye 10 times per second.
>>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a
>>>>>>>>>>>>>> SINGLE SECOND
>>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching.
>>>>>>>>>>>>>> Now scale that up to 1000 concurrent rooms with  4x4 meetings where every
>>>>>>>>>>>>>> user has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>>>>>> really?!
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is
>>>>>>>>>>>>>>> why the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having it
>>>>>>>>>>>>>>> as DB object was the only option to have user count in the room (in case
>>>>>>>>>>>>>>> Rooms are on the different servers).
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>>> I hope everything except audio and video will move to Wicket
>>>>>>>>>>>>>>> :)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap
>>>>>>>>>>>>>>>> stored in the memory is slower then doing a single query for every entry of
>>>>>>>>>>>>>>>> the map ?
>>>>>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>>> and now this single line is replaced by a Database query.
>>>>>>>>>>>>>>>> The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash
>>>>>>>>>>>>>>>>>> map to get subset required.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these changes
>>>>>>>>>>>>>>>>>> are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you
>>>>>>>>>>>>>>>>>>> think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and
>>>>>>>>>>>>>>>>>>> more.
>>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it should
>>>>>>>>>>>>>>>>>>> stay in the session.
>>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>>> We are making a real time application, there is no
>>>>>>>>>>>>>>>>>>> chance to run queries in sync methods.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating through
>>>>>>>>>>>>>>>>>>>> the Red5 Connections.
>>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import.
>>>>>>>>>>>>>>>>>>>> So maybe annotate it with:
>>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r
>>>>>>>>>>>>>>>>>>>>> LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false
>>>>>>>>>>>>>>>>>>>>> ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT
>>>>>>>>>>>>>>>>>>>>> c.room FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>>> +               + "WHERE
>>>>>>>>>>>>>>>>>>>>> c.organisation.organisation_id = :orgId "
>>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId)
>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>> org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>>> Form<A
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null
>>>>>>>>>>>>>>>>>>>>> && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>>                                         closeOnEscape:
>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>>                                         , resizable:
>>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>>>>                                         , autoOpen:
>>>>>>>>>>>>>>>>>>>>> false
>>>>>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>   <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>>   <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends
>>>>>>>>>>>>>>>>>>>>> UserP
>>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> +                               if (start.equals(end))
>>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
the standard call to get a room client is not to get the roomclients by its
roomid.
The standard call to get a room client is to get the roomclient by its
streamid !!!
And this call is done for every RoomClient per sync method.
So if there are 100 clients in a room = 100 db calls per sync.
I thought I have tried to explain the calculation.

I just don't understand this whole discussion, we have a single
requirement:
Calculate the list of users per room.
And now we need to switch a session object to the database?

I don't see a need for a hybrid solution to have session objects twice.
There will be multiple issues in syncing the information in the session
objects:
A single user can create 2 or 3 RTMP connection to the server.
It will not be get simpler by your solution:
If the users connects as "Screensharing Client" your logic will not detect
it.
If the user connects as "Audio/Video Client" your logic will not detect it.
So actually you will have multiple methods in the ScopeApplicationAdapter
where you will have to sync the session object to the database otherwise
the database object is of quite limited use.

I really don't think splitting up that logic to database and session makes
things more easy.
All you want is to use a query like "SELECT ROOM JOIN FETCH ROOMATTENDEE" ;)
Just for having such a query we are not going to switch around a session
object to the database.
It just has too many drawbacks.

Sebastian

2012/10/26 Maxim Solodovnik <so...@gmail.com>

> I'm afraid I never can get why do we need to perform RPC call (no matter
> by client or by server) if we already have common DB and can use it.
>
> DB can be used even if RoomClient is not DB Entity.
>
> I still think that if code will be changed from
>         for (Set<IConnection> conset : conCollection) {
>             for (IConnection conn : conset) {
>                 if (conn != null) {
>                     RoomClient rcl = this.clientListManager
>                             .getClientByStreamId(conn
>                                     .getClient().getId());
>                     if (rcl == null) {
>                         // continue;
>                     } else if (rcl.getIsScreenClient() != null
>                             && rcl.getIsScreenClient()) {
>                         // continue;
>                     } else {
>                         if (!streamid.equals(rcl.getStreamid())) {
>                             // do staff here
>                         }
>                     }
>                 }
>             }
>         }
>
>
> to:
> for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
>       // do same staff here
> }
>
> we will have
> 1) only one DB call per broadcast
> 2) 1 loop instead 2 nested loops
> 3) no 3 level filtering inside second loop
>
>
> To implement your solution and remove RoomClient from DB, I propose the
> following:
> 1) remove RoomClient from DB
> 2) add RoomAttendee Entity to the DB (it will contain minimal attendee
> info and will be queried only to get room clients and their basic info
> while getting list of users currently in room)
>
> Is it OK?
>
> On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> Now userC opens OM installed on serverA
>> => userC asks for the list of rooms including the number of users.
>> The server side will calc the users per room. Either by calculating the
>> rooms locally, or by perrforming a RPC call to the connected server to get
>> the list of current usercount per room.
>> userC will only peform a single call, server might do mulitple calls to
>> calc the usercount, but it sends back a single answer.
>> So there is no multiple calls needed.
>> For a future iteration we might also think about a master slave principle
>> where the slave always automatically pushes current usercount to the
>> master, so there is no need for the master to ask for the usercount.
>>
>> However for the time being I think it is acceptable, with a scenario of
>> 2-3 servers in the cluster such a RPC call might take 2 seconds longer then
>> currently, but I think that is ok for now.
>>
>> Sebastian
>>
>>
>> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>>
>>> Hello Sebastian,
>>>
>>> Imagine the following situation:
>>> We have 2 servers: serverA and serverB, both have OM installed with same
>>> DB
>>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>>> serverB) each have 10 active users in it right now
>>>
>>> Now userC opens OM installed on serverA
>>> In the list of rooms he can see roomA (user count can be get by counting
>>> connections) and roomB (no user count)
>>>
>>> performing RTMP call from client to both server seems to be possible but
>>> complicated solution for the LZX client, but it seems to
>>> me unacceptable for the wicket client.
>>>
>>>
>>>
>>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> How do you handle rooms in general in that solution, is a single room
>>>> always on the same server instance.
>>>> Or in other words:
>>>> Can it happens that two users are in the same room but on different
>>>> servers?
>>>> Cause from my point of view that is impossible.
>>>> You can't stream a video from server instance 1 and from instance 2 at
>>>> the same time.
>>>> So users of a one room are always on the same server.
>>>> That should also make the calculation easier.
>>>>
>>>> The other point is of course you will have to write a script that will
>>>> collect the number of users per room from all server instances and then
>>>> calculate the sum of it.
>>>> I would collect this on the server side and then give the client just
>>>> the result of it. For the client it would look like a single RPC call,
>>>> while on server side, the server asks each instance for its usage
>>>> numbers/statistics.
>>>>
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> If there is only 1 server - all your solutions will work.
>>>>> But imaging we have 2 servers. Each have its own room full of clients.
>>>>>
>>>>> Now User enters server1 and would like to see how much users in each
>>>>> room.
>>>>> But it is impossible since server1 only have connections/roomClients
>>>>> only for 1 server, and have no information regarding second one.
>>>>>
>>>>>
>>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> *I see no other way to get the number of users (per server)*
>>>>>> => There are at least three alternative ways to get this number:
>>>>>> a) You count the number of connection of a certain scope and then
>>>>>> take the sum of it
>>>>>> This will give you the total number of connections, no matter if
>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>> b) You count the total number of RoomClients from the current session
>>>>>> This will give you the total number of connections, no matter if
>>>>>> audio/video, conferencing or a screensharing connection.
>>>>>> c) You count the total number of RoomClients from the current
>>>>>> session, but you filter the result based on if the RoomClient is a
>>>>>> Audio/Video client or a Screensharing client
>>>>>> With this method you would be able to calc the exact number of
>>>>>> Audio/Video connection
>>>>>>
>>>>>> Which of those would fit yours?
>>>>>> Or did I misunderstood something?
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>>
>>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> Hello Sebastian,
>>>>>>>
>>>>>>> I'm afraid we need something like "lightweight RoomClient" in the DB
>>>>>>> to resolve 3)
>>>>>>> This can be done without performance degradation.
>>>>>>> I see no other way to get the number of users.
>>>>>>>
>>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> So will we find a consens here? :)
>>>>>>>>
>>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>>> 3) To have the number of users per server instance there is no need
>>>>>>>> to have the RoomClient in the database.
>>>>>>>>
>>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>
>>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>>> connection.
>>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>>> This would give a rough idea. But as you don't know how many of
>>>>>>>>> those connection are screensharing or Audio/Video you can't tell how many
>>>>>>>>> users exactly there are.
>>>>>>>>>
>>>>>>>>> If you want to share this information with others I would suggest
>>>>>>>>> you simply add a SOAP/REST call and in that sense query the number of users
>>>>>>>>> via a HTTP call.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> If I remember correctly I have added RoomClient to the DB since I
>>>>>>>>>> need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>>>>
>>>>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>>
>>>>>>>>>>> It is no option to stay with it, how can we offer OpenMeetings
>>>>>>>>>>> to be scalable to 1000 concurrent users? We would have to limit it to 250.
>>>>>>>>>>> Also it would become mandatory to have the database server on the same
>>>>>>>>>>> machine as the red5 server. Otherwise you have performance bottlenecks. Can
>>>>>>>>>>> you imagine what kind of negative public feedback we will have if every
>>>>>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>>>>>> server on another instance of your network?
>>>>>>>>>>>
>>>>>>>>>>> Sorry but it is not possible. Also not for a temporary solution.
>>>>>>>>>>> We can't sell this product like that and claim to have 1000 user sessions
>>>>>>>>>>> per server unit.
>>>>>>>>>>>
>>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>>>>>>> future.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>>
>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>    }
>>>>>>>>>>>>> }
>>>>>>>>>>>>>
>>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>>> There are _some_ implementations where it was needed that you
>>>>>>>>>>>>> need to get the RoomClient by its public SID. However this usage was quite
>>>>>>>>>>>>> limited.
>>>>>>>>>>>>>
>>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>>> The maps key was the streamid. And the streamid was obtained
>>>>>>>>>>>>> from the IConnection of each stream.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>>> Line 118, that was the function that was mainly in use all
>>>>>>>>>>>>> over the application.
>>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Search in the ScopeApplicationAdapter for
>>>>>>>>>>>>> "getClientByStreamId" => 52 of matches.
>>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>>> And if you iterate like described through all connection (like
>>>>>>>>>>>>> it is in EVERY snyc method)
>>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>>> Think about the green dot that blinks every time you speak in
>>>>>>>>>>>>> the video pod:
>>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>>> If you have a quite good and sensitive micro it will flush 10
>>>>>>>>>>>>> mabye 10 times per second.
>>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>>>>>>> SECOND
>>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching.
>>>>>>>>>>>>> Now scale that up to 1000 concurrent rooms with  4x4 meetings where every
>>>>>>>>>>>>> user has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>>>>> really?!
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is why
>>>>>>>>>>>>>> the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having it
>>>>>>>>>>>>>> as DB object was the only option to have user count in the room (in case
>>>>>>>>>>>>>> Rooms are on the different servers).
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I believe right now
>>>>>>>>>>>>>> org.apache.openmeetings.web.app.WebSession will be session object.
>>>>>>>>>>>>>> I hope everything except audio and video will move to Wicket
>>>>>>>>>>>>>> :)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap stored
>>>>>>>>>>>>>>> in the memory is slower then doing a single query for every entry of the
>>>>>>>>>>>>>>> map ?
>>>>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>>> and now this single line is replaced by a Database query.
>>>>>>>>>>>>>>> The performance of this single line  is ... I guess smaller then 1
>>>>>>>>>>>>>>> millisecond. How can you say that a "Right now I think the current code
>>>>>>>>>>>>>>> should work faster or the same as previous one." :)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented
>>>>>>>>>>>>>>>>> cluster.
>>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash
>>>>>>>>>>>>>>>>> map to get subset required.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> But I hope everything is not so slow since these changes
>>>>>>>>>>>>>>>>> are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you
>>>>>>>>>>>>>>>>>> think about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and
>>>>>>>>>>>>>>>>>> more.
>>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it should
>>>>>>>>>>>>>>>>>> stay in the session.
>>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>>> We are making a real time application, there is no chance
>>>>>>>>>>>>>>>>>> to run queries in sync methods.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> We calc the current users online by iterating through
>>>>>>>>>>>>>>>>>>> the Red5 Connections.
>>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import.
>>>>>>>>>>>>>>>>>>> So maybe annotate it with:
>>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r
>>>>>>>>>>>>>>>>>>>> LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false
>>>>>>>>>>>>>>>>>>>> ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room
>>>>>>>>>>>>>>>>>>>> FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id
>>>>>>>>>>>>>>>>>>>> = :orgId "
>>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends
>>>>>>>>>>>>>>>>>>>> Form<A
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes>
>>>>>>>>>>>>>>>>>>>> roomType = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null
>>>>>>>>>>>>>>>>>>>> && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>>                                         closeOnEscape:
>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>>                                         , resizable:
>>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>>>                                         , autoOpen:
>>>>>>>>>>>>>>>>>>>> false
>>>>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends
>>>>>>>>>>>>>>>>>>>> UserP
>>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> WBR
>>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
I'm afraid I never can get why do we need to perform RPC call (no matter by
client or by server) if we already have common DB and can use it.

DB can be used even if RoomClient is not DB Entity.

I still think that if code will be changed from
        for (Set<IConnection> conset : conCollection) {
            for (IConnection conn : conset) {
                if (conn != null) {
                    RoomClient rcl = this.clientListManager
                            .getClientByStreamId(conn
                                    .getClient().getId());
                    if (rcl == null) {
                        // continue;
                    } else if (rcl.getIsScreenClient() != null
                            && rcl.getIsScreenClient()) {
                        // continue;
                    } else {
                        if (!streamid.equals(rcl.getStreamid())) {
                            // do staff here
                        }
                    }
                }
            }
        }


to:
for (RoomClient rc : clientListManager.getClientListByRoom(roomId)) {
      // do same staff here
}

we will have
1) only one DB call per broadcast
2) 1 loop instead 2 nested loops
3) no 3 level filtering inside second loop


To implement your solution and remove RoomClient from DB, I propose the
following:
1) remove RoomClient from DB
2) add RoomAttendee Entity to the DB (it will contain minimal attendee info
and will be queried only to get room clients and their basic info while
getting list of users currently in room)

Is it OK?

On Fri, Oct 26, 2012 at 2:11 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> Now userC opens OM installed on serverA
> => userC asks for the list of rooms including the number of users.
> The server side will calc the users per room. Either by calculating the
> rooms locally, or by perrforming a RPC call to the connected server to get
> the list of current usercount per room.
> userC will only peform a single call, server might do mulitple calls to
> calc the usercount, but it sends back a single answer.
> So there is no multiple calls needed.
> For a future iteration we might also think about a master slave principle
> where the slave always automatically pushes current usercount to the
> master, so there is no need for the master to ask for the usercount.
>
> However for the time being I think it is acceptable, with a scenario of
> 2-3 servers in the cluster such a RPC call might take 2 seconds longer then
> currently, but I think that is ok for now.
>
> Sebastian
>
>
> 2012/10/26 Maxim Solodovnik <so...@gmail.com>
>
>> Hello Sebastian,
>>
>> Imagine the following situation:
>> We have 2 servers: serverA and serverB, both have OM installed with same
>> DB
>> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
>> serverB) each have 10 active users in it right now
>>
>> Now userC opens OM installed on serverA
>> In the list of rooms he can see roomA (user count can be get by counting
>> connections) and roomB (no user count)
>>
>> performing RTMP call from client to both server seems to be possible but
>> complicated solution for the LZX client, but it seems to
>> me unacceptable for the wicket client.
>>
>>
>>
>> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> How do you handle rooms in general in that solution, is a single room
>>> always on the same server instance.
>>> Or in other words:
>>> Can it happens that two users are in the same room but on different
>>> servers?
>>> Cause from my point of view that is impossible.
>>> You can't stream a video from server instance 1 and from instance 2 at
>>> the same time.
>>> So users of a one room are always on the same server.
>>> That should also make the calculation easier.
>>>
>>> The other point is of course you will have to write a script that will
>>> collect the number of users per room from all server instances and then
>>> calculate the sum of it.
>>> I would collect this on the server side and then give the client just
>>> the result of it. For the client it would look like a single RPC call,
>>> while on server side, the server asks each instance for its usage
>>> numbers/statistics.
>>>
>>>
>>> Sebastian
>>>
>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> If there is only 1 server - all your solutions will work.
>>>> But imaging we have 2 servers. Each have its own room full of clients.
>>>>
>>>> Now User enters server1 and would like to see how much users in each
>>>> room.
>>>> But it is impossible since server1 only have connections/roomClients
>>>> only for 1 server, and have no information regarding second one.
>>>>
>>>>
>>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> *I see no other way to get the number of users (per server)*
>>>>> => There are at least three alternative ways to get this number:
>>>>> a) You count the number of connection of a certain scope and then take
>>>>> the sum of it
>>>>> This will give you the total number of connections, no matter if
>>>>> audio/video, conferencing or a screensharing connection.
>>>>> b) You count the total number of RoomClients from the current session
>>>>> This will give you the total number of connections, no matter if
>>>>> audio/video, conferencing or a screensharing connection.
>>>>> c) You count the total number of RoomClients from the current session,
>>>>> but you filter the result based on if the RoomClient is a Audio/Video
>>>>> client or a Screensharing client
>>>>> With this method you would be able to calc the exact number of
>>>>> Audio/Video connection
>>>>>
>>>>> Which of those would fit yours?
>>>>> Or did I misunderstood something?
>>>>>
>>>>> Sebastian
>>>>>
>>>>>
>>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> Hello Sebastian,
>>>>>>
>>>>>> I'm afraid we need something like "lightweight RoomClient" in the DB
>>>>>> to resolve 3)
>>>>>> This can be done without performance degradation.
>>>>>> I see no other way to get the number of users.
>>>>>>
>>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> So will we find a consens here? :)
>>>>>>>
>>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>>> 3) To have the number of users per server instance there is no need
>>>>>>> to have the RoomClient in the database.
>>>>>>>
>>>>>>> Can we find a consens based on those resolutions?
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>
>>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>>> connection.
>>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>>> This would give a rough idea. But as you don't know how many of
>>>>>>>> those connection are screensharing or Audio/Video you can't tell how many
>>>>>>>> users exactly there are.
>>>>>>>>
>>>>>>>> If you want to share this information with others I would suggest
>>>>>>>> you simply add a SOAP/REST call and in that sense query the number of users
>>>>>>>> via a HTTP call.
>>>>>>>>
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> If I remember correctly I have added RoomClient to the DB since I
>>>>>>>>> need mechanism to retrieve how much users are currently in the room.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>>>
>>>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>>
>>>>>>>>>> It is no option to stay with it, how can we offer OpenMeetings to
>>>>>>>>>> be scalable to 1000 concurrent users? We would have to limit it to 250.
>>>>>>>>>> Also it would become mandatory to have the database server on the same
>>>>>>>>>> machine as the red5 server. Otherwise you have performance bottlenecks. Can
>>>>>>>>>> you imagine what kind of negative public feedback we will have if every
>>>>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>>>>> server on another instance of your network?
>>>>>>>>>>
>>>>>>>>>> Sorry but it is not possible. Also not for a temporary solution.
>>>>>>>>>> We can't sell this product like that and claim to have 1000 user sessions
>>>>>>>>>> per server unit.
>>>>>>>>>>
>>>>>>>>>> What requirements do exist to store the RoomClient in the
>>>>>>>>>> database and what is needed to be done to remove it from the db again?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>>>>>> future.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Sorry but:
>>>>>>>>>>>>
>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>    }
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> That is simply not true.
>>>>>>>>>>>> There are _some_ implementations where it was needed that you
>>>>>>>>>>>> need to get the RoomClient by its public SID. However this usage was quite
>>>>>>>>>>>> limited.
>>>>>>>>>>>>
>>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>>> The maps key was the streamid. And the streamid was obtained
>>>>>>>>>>>> from the IConnection of each stream.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>>> Line 118, that was the function that was mainly in use all over
>>>>>>>>>>>> the application.
>>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>>
>>>>>>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId"
>>>>>>>>>>>> => 52 of matches.
>>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>>> And if you iterate like described through all connection (like
>>>>>>>>>>>> it is in EVERY snyc method)
>>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>>> Think about the green dot that blinks every time you speak in
>>>>>>>>>>>> the video pod:
>>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>>> If you have a quite good and sensitive micro it will flush 10
>>>>>>>>>>>> mabye 10 times per second.
>>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>>>>>> SECOND
>>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every user
>>>>>>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>>>> really?!
>>>>>>>>>>>>
>>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>>
>>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>>    }
>>>>>>>>>>>>> }
>>>>>>>>>>>>>
>>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is why
>>>>>>>>>>>>> the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>>
>>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having it
>>>>>>>>>>>>> as DB object was the only option to have user count in the room (in case
>>>>>>>>>>>>> Rooms are on the different servers).
>>>>>>>>>>>>>
>>>>>>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession
>>>>>>>>>>>>> will be session object.
>>>>>>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap stored
>>>>>>>>>>>>>> in the memory is slower then doing a single query for every entry of the
>>>>>>>>>>>>>> map ?
>>>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash
>>>>>>>>>>>>>>>> map to get subset required.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> But I hope everything is not so slow since these changes
>>>>>>>>>>>>>>>> are present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and
>>>>>>>>>>>>>>>>> more.
>>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it should
>>>>>>>>>>>>>>>>> stay in the session.
>>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>>> We are making a real time application, there is no chance
>>>>>>>>>>>>>>>>> to run queries in sync methods.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> We calc the current users online by iterating through the
>>>>>>>>>>>>>>>>>> Red5 Connections.
>>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import.
>>>>>>>>>>>>>>>>>> So maybe annotate it with:
>>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r
>>>>>>>>>>>>>>>>>>> LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false
>>>>>>>>>>>>>>>>>>> ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room
>>>>>>>>>>>>>>>>>>> FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id
>>>>>>>>>>>>>>>>>>> = :orgId "
>>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends
>>>>>>>>>>>>>>>>>>> Form<A
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType
>>>>>>>>>>>>>>>>>>> = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null
>>>>>>>>>>>>>>>>>>> && getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>>                                         closeOnEscape:
>>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><span wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends
>>>>>>>>>>>>>>>>>>> UserP
>>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> WBR
>>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
Now userC opens OM installed on serverA
=> userC asks for the list of rooms including the number of users.
The server side will calc the users per room. Either by calculating the
rooms locally, or by perrforming a RPC call to the connected server to get
the list of current usercount per room.
userC will only peform a single call, server might do mulitple calls to
calc the usercount, but it sends back a single answer.
So there is no multiple calls needed.
For a future iteration we might also think about a master slave principle
where the slave always automatically pushes current usercount to the
master, so there is no need for the master to ask for the usercount.

However for the time being I think it is acceptable, with a scenario of 2-3
servers in the cluster such a RPC call might take 2 seconds longer then
currently, but I think that is ok for now.

Sebastian

2012/10/26 Maxim Solodovnik <so...@gmail.com>

> Hello Sebastian,
>
> Imagine the following situation:
> We have 2 servers: serverA and serverB, both have OM installed with same DB
> We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
> serverB) each have 10 active users in it right now
>
> Now userC opens OM installed on serverA
> In the list of rooms he can see roomA (user count can be get by counting
> connections) and roomB (no user count)
>
> performing RTMP call from client to both server seems to be possible but
> complicated solution for the LZX client, but it seems to
> me unacceptable for the wicket client.
>
>
>
> On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> How do you handle rooms in general in that solution, is a single room
>> always on the same server instance.
>> Or in other words:
>> Can it happens that two users are in the same room but on different
>> servers?
>> Cause from my point of view that is impossible.
>> You can't stream a video from server instance 1 and from instance 2 at
>> the same time.
>> So users of a one room are always on the same server.
>> That should also make the calculation easier.
>>
>> The other point is of course you will have to write a script that will
>> collect the number of users per room from all server instances and then
>> calculate the sum of it.
>> I would collect this on the server side and then give the client just the
>> result of it. For the client it would look like a single RPC call, while on
>> server side, the server asks each instance for its usage numbers/statistics.
>>
>>
>> Sebastian
>>
>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>
>>> If there is only 1 server - all your solutions will work.
>>> But imaging we have 2 servers. Each have its own room full of clients.
>>>
>>> Now User enters server1 and would like to see how much users in each
>>> room.
>>> But it is impossible since server1 only have connections/roomClients
>>> only for 1 server, and have no information regarding second one.
>>>
>>>
>>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> *I see no other way to get the number of users (per server)*
>>>> => There are at least three alternative ways to get this number:
>>>> a) You count the number of connection of a certain scope and then take
>>>> the sum of it
>>>> This will give you the total number of connections, no matter if
>>>> audio/video, conferencing or a screensharing connection.
>>>> b) You count the total number of RoomClients from the current session
>>>> This will give you the total number of connections, no matter if
>>>> audio/video, conferencing or a screensharing connection.
>>>> c) You count the total number of RoomClients from the current session,
>>>> but you filter the result based on if the RoomClient is a Audio/Video
>>>> client or a Screensharing client
>>>> With this method you would be able to calc the exact number of
>>>> Audio/Video connection
>>>>
>>>> Which of those would fit yours?
>>>> Or did I misunderstood something?
>>>>
>>>> Sebastian
>>>>
>>>>
>>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> Hello Sebastian,
>>>>>
>>>>> I'm afraid we need something like "lightweight RoomClient" in the DB
>>>>> to resolve 3)
>>>>> This can be done without performance degradation.
>>>>> I see no other way to get the number of users.
>>>>>
>>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> So will we find a consens here? :)
>>>>>>
>>>>>> 1) No DB query in Sync methods to keep performance up
>>>>>> 2) Session objects should not stay in a database but in memory
>>>>>> 3) To have the number of users per server instance there is no need
>>>>>> to have the RoomClient in the database.
>>>>>>
>>>>>> Can we find a consens based on those resolutions?
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>
>>>>>> Practically in this case you would have to iterate thorugh the
>>>>>>> connection.
>>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>>> This would give a rough idea. But as you don't know how many of
>>>>>>> those connection are screensharing or Audio/Video you can't tell how many
>>>>>>> users exactly there are.
>>>>>>>
>>>>>>> If you want to share this information with others I would suggest
>>>>>>> you simply add a SOAP/REST call and in that sense query the number of users
>>>>>>> via a HTTP call.
>>>>>>>
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> If I remember correctly I have added RoomClient to the DB since I
>>>>>>>> need mechanism to retrieve how much users are currently in the room.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>>
>>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>>
>>>>>>>>> It is no option to stay with it, how can we offer OpenMeetings to
>>>>>>>>> be scalable to 1000 concurrent users? We would have to limit it to 250.
>>>>>>>>> Also it would become mandatory to have the database server on the same
>>>>>>>>> machine as the red5 server. Otherwise you have performance bottlenecks. Can
>>>>>>>>> you imagine what kind of negative public feedback we will have if every
>>>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>>>> server on another instance of your network?
>>>>>>>>>
>>>>>>>>> Sorry but it is not possible. Also not for a temporary solution.
>>>>>>>>> We can't sell this product like that and claim to have 1000 user sessions
>>>>>>>>> per server unit.
>>>>>>>>>
>>>>>>>>> What requirements do exist to store the RoomClient in the database
>>>>>>>>> and what is needed to be done to remove it from the db again?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>>>>> future.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> Sorry but:
>>>>>>>>>>>
>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>       return rc;
>>>>>>>>>>>    }
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> That is simply not true.
>>>>>>>>>>> There are _some_ implementations where it was needed that you
>>>>>>>>>>> need to get the RoomClient by its public SID. However this usage was quite
>>>>>>>>>>> limited.
>>>>>>>>>>>
>>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>>> The maps key was the streamid. And the streamid was obtained
>>>>>>>>>>> from the IConnection of each stream.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>>> Line 118, that was the function that was mainly in use all over
>>>>>>>>>>> the application.
>>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>>
>>>>>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId"
>>>>>>>>>>> => 52 of matches.
>>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>>> And if you iterate like described through all connection (like
>>>>>>>>>>> it is in EVERY snyc method)
>>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>>> Think about the green dot that blinks every time you speak in
>>>>>>>>>>> the video pod:
>>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>>> If you have a quite good and sensitive micro it will flush 10
>>>>>>>>>>> mabye 10 times per second.
>>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>>>>> SECOND
>>>>>>>>>>> => that is just impossible !!
>>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every user
>>>>>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>>> really?!
>>>>>>>>>>>
>>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>>
>>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>>       return rc;
>>>>>>>>>>>>    }
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>>> Right now we can filter all sessions with 1 query this is why
>>>>>>>>>>>> the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>>
>>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having it as
>>>>>>>>>>>> DB object was the only option to have user count in the room (in case Rooms
>>>>>>>>>>>> are on the different servers).
>>>>>>>>>>>>
>>>>>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession
>>>>>>>>>>>> will be session object.
>>>>>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>
>>>>>>>>>>>>> you can't persist on the argumentation that a HashMap stored
>>>>>>>>>>>>> in the memory is slower then doing a single query for every entry of the
>>>>>>>>>>>>> map ?
>>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>>>>>
>>>>>>>>>>>>> I guess you had some other requirements that made you
>>>>>>>>>>>>> implement this.
>>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Could you explain why there is a need for having the
>>>>>>>>>>>>> RoomClient in the database? Maybe we can resolve those requirements
>>>>>>>>>>>>> differently so that we can have the RoomClient back in memory.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map
>>>>>>>>>>>>>>> to get subset required.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I ask that critical as some queries require to sync
>>>>>>>>>>>>>>>> messages to all clients of a room.
>>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and
>>>>>>>>>>>>>>>> more.
>>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it should
>>>>>>>>>>>>>>>> stay in the session.
>>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>>> We are making a real time application, there is no chance
>>>>>>>>>>>>>>>> to run queries in sync methods.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We calc the current users online by iterating through the
>>>>>>>>>>>>>>>>> Red5 Connections.
>>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements
>>>>>>>>>>>>>>>>>> OmDAO<Ro
>>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r
>>>>>>>>>>>>>>>>>> LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false
>>>>>>>>>>>>>>>>>> ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room
>>>>>>>>>>>>>>>>>> FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation>
>>>>>>>>>>>>>>>>>> roomOrganisations = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>         public CalendarForm(String id,
>>>>>>>>>>>>>>>>>> IModel<Appointment> model) {
>>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends
>>>>>>>>>>>>>>>>>> Form<A
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType
>>>>>>>>>>>>>>>>>> = new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>>>>>>                                         closeOnEscape:
>>>>>>>>>>>>>>>>>> true
>>>>>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> <td><input type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>>> <td><input type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends
>>>>>>>>>>>>>>>>>> UserP
>>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> WBR
>>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
Hello Sebastian,

Imagine the following situation:
We have 2 servers: serverA and serverB, both have OM installed with same DB
We have 2 rooms: roomA (assigned to serverA) and roomB (assigned to
serverB) each have 10 active users in it right now

Now userC opens OM installed on serverA
In the list of rooms he can see roomA (user count can be get by counting
connections) and roomB (no user count)

performing RTMP call from client to both server seems to be possible but
complicated solution for the LZX client, but it seems to
me unacceptable for the wicket client.



On Wed, Oct 24, 2012 at 5:13 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> How do you handle rooms in general in that solution, is a single room
> always on the same server instance.
> Or in other words:
> Can it happens that two users are in the same room but on different
> servers?
> Cause from my point of view that is impossible.
> You can't stream a video from server instance 1 and from instance 2 at the
> same time.
> So users of a one room are always on the same server.
> That should also make the calculation easier.
>
> The other point is of course you will have to write a script that will
> collect the number of users per room from all server instances and then
> calculate the sum of it.
> I would collect this on the server side and then give the client just the
> result of it. For the client it would look like a single RPC call, while on
> server side, the server asks each instance for its usage numbers/statistics.
>
>
> Sebastian
>
> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>
>> If there is only 1 server - all your solutions will work.
>> But imaging we have 2 servers. Each have its own room full of clients.
>>
>> Now User enters server1 and would like to see how much users in each room.
>> But it is impossible since server1 only have connections/roomClients only
>> for 1 server, and have no information regarding second one.
>>
>>
>> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> *I see no other way to get the number of users (per server)*
>>> => There are at least three alternative ways to get this number:
>>> a) You count the number of connection of a certain scope and then take
>>> the sum of it
>>> This will give you the total number of connections, no matter if
>>> audio/video, conferencing or a screensharing connection.
>>> b) You count the total number of RoomClients from the current session
>>> This will give you the total number of connections, no matter if
>>> audio/video, conferencing or a screensharing connection.
>>> c) You count the total number of RoomClients from the current session,
>>> but you filter the result based on if the RoomClient is a Audio/Video
>>> client or a Screensharing client
>>> With this method you would be able to calc the exact number of
>>> Audio/Video connection
>>>
>>> Which of those would fit yours?
>>> Or did I misunderstood something?
>>>
>>> Sebastian
>>>
>>>
>>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> Hello Sebastian,
>>>>
>>>> I'm afraid we need something like "lightweight RoomClient" in the DB to
>>>> resolve 3)
>>>> This can be done without performance degradation.
>>>> I see no other way to get the number of users.
>>>>
>>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> So will we find a consens here? :)
>>>>>
>>>>> 1) No DB query in Sync methods to keep performance up
>>>>> 2) Session objects should not stay in a database but in memory
>>>>> 3) To have the number of users per server instance there is no need to
>>>>> have the RoomClient in the database.
>>>>>
>>>>> Can we find a consens based on those resolutions?
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>>
>>>>> Practically in this case you would have to iterate thorugh the
>>>>>> connection.
>>>>>> You could also call IConnection => getConnection => getSize.
>>>>>> This would give a rough idea. But as you don't know how many of those
>>>>>> connection are screensharing or Audio/Video you can't tell how many users
>>>>>> exactly there are.
>>>>>>
>>>>>> If you want to share this information with others I would suggest you
>>>>>> simply add a SOAP/REST call and in that sense query the number of users via
>>>>>> a HTTP call.
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> If I remember correctly I have added RoomClient to the DB since I
>>>>>>> need mechanism to retrieve how much users are currently in the room.
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>>
>>>>>>>> We will also stay with our Red5 implementation for the next 6
>>>>>>>> months as we have no alternative to stream audio/video in HTML5.
>>>>>>>>
>>>>>>>> It is no option to stay with it, how can we offer OpenMeetings to
>>>>>>>> be scalable to 1000 concurrent users? We would have to limit it to 250.
>>>>>>>> Also it would become mandatory to have the database server on the same
>>>>>>>> machine as the red5 server. Otherwise you have performance bottlenecks. Can
>>>>>>>> you imagine what kind of negative public feedback we will have if every
>>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>>> server on another instance of your network?
>>>>>>>>
>>>>>>>> Sorry but it is not possible. Also not for a temporary solution. We
>>>>>>>> can't sell this product like that and claim to have 1000 user sessions per
>>>>>>>> server unit.
>>>>>>>>
>>>>>>>> What requirements do exist to store the RoomClient in the database
>>>>>>>> and what is needed to be done to remove it from the db again?
>>>>>>>>
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>>>> future.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> Sorry but:
>>>>>>>>>>
>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>       return rc;
>>>>>>>>>>    }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> That is simply not true.
>>>>>>>>>> There are _some_ implementations where it was needed that you
>>>>>>>>>> need to get the RoomClient by its public SID. However this usage was quite
>>>>>>>>>> limited.
>>>>>>>>>>
>>>>>>>>>> In general it was the way I described it:
>>>>>>>>>> The maps key was the streamid. And the streamid was obtained from
>>>>>>>>>> the IConnection of each stream.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>>> Line 118, that was the function that was mainly in use all over
>>>>>>>>>> the application.
>>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>>
>>>>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId"
>>>>>>>>>> => 52 of matches.
>>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>>> And if you iterate like described through all connection (like it
>>>>>>>>>> is in EVERY snyc method)
>>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>>> Think about the green dot that blinks every time you speak in the
>>>>>>>>>> video pod:
>>>>>>>>>> If it gets visible => one sync message
>>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>>> If you have a quite good and sensitive micro it will flush 10
>>>>>>>>>> mabye 10 times per second.
>>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>>>> SECOND
>>>>>>>>>> => that is just impossible !!
>>>>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every user
>>>>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>>>>> really?!
>>>>>>>>>>
>>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> Previous solution was:
>>>>>>>>>>>
>>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>>       return rc;
>>>>>>>>>>>    }
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>>> Right now we can filter all sessions with 1 query this is why
>>>>>>>>>>> the code can work faster (after minor changes in iterating logic)
>>>>>>>>>>>
>>>>>>>>>>> I'm not insist RoomClient should be DB object. But having it as
>>>>>>>>>>> DB object was the only option to have user count in the room (in case Rooms
>>>>>>>>>>> are on the different servers).
>>>>>>>>>>>
>>>>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession
>>>>>>>>>>> will be session object.
>>>>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>
>>>>>>>>>>>> you can't persist on the argumentation that a HashMap stored in
>>>>>>>>>>>> the memory is slower then doing a single query for every entry of the map ?
>>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>>>>
>>>>>>>>>>>> I guess you had some other requirements that made you implement
>>>>>>>>>>>> this.
>>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>>> performance in the future.
>>>>>>>>>>>>
>>>>>>>>>>>> Could you explain why there is a need for having the RoomClient
>>>>>>>>>>>> in the database? Maybe we can resolve those requirements differently so
>>>>>>>>>>>> that we can have the RoomClient back in memory.
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>>>>> Current changes only make the calls faster (since DB is
>>>>>>>>>>>>>> quered only once)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map
>>>>>>>>>>>>>> to get subset required.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I ask that critical as some queries require to sync messages
>>>>>>>>>>>>>>> to all clients of a room.
>>>>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and
>>>>>>>>>>>>>>> more.
>>>>>>>>>>>>>>> The RoomClient is a typical Session object and it should
>>>>>>>>>>>>>>> stay in the session.
>>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>>> We are making a real time application, there is no chance to
>>>>>>>>>>>>>>> run queries in sync methods.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We calc the current users online by iterating through the
>>>>>>>>>>>>>>>> Red5 Connections.
>>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r
>>>>>>>>>>>>>>>>> LEFT JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false
>>>>>>>>>>>>>>>>> ORDER BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long
>>>>>>>>>>>>>>>>> orgId) {
>>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room
>>>>>>>>>>>>>>>>> FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND
>>>>>>>>>>>>>>>>> c.room.deleted = false "
>>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC",
>>>>>>>>>>>>>>>>> Rooms.class);
>>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations
>>>>>>>>>>>>>>>>> = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>>>>>>> model) {
>>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType =
>>>>>>>>>>>>>>>>> new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>>> AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>>> +               List<Rooms> result = new
>>>>>>>>>>>>>>>>> ArrayList<Rooms>();
>>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>> <td><select wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> <td><select wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>>> <td><select wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> <td><select wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><select wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><select wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends
>>>>>>>>>>>>>>>>> UserP
>>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> WBR
>>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
How do you handle rooms in general in that solution, is a single room
always on the same server instance.
Or in other words:
Can it happens that two users are in the same room but on different servers?
Cause from my point of view that is impossible.
You can't stream a video from server instance 1 and from instance 2 at the
same time.
So users of a one room are always on the same server.
That should also make the calculation easier.

The other point is of course you will have to write a script that will
collect the number of users per room from all server instances and then
calculate the sum of it.
I would collect this on the server side and then give the client just the
result of it. For the client it would look like a single RPC call, while on
server side, the server asks each instance for its usage numbers/statistics.

Sebastian

2012/10/24 Maxim Solodovnik <so...@gmail.com>

> If there is only 1 server - all your solutions will work.
> But imaging we have 2 servers. Each have its own room full of clients.
>
> Now User enters server1 and would like to see how much users in each room.
> But it is impossible since server1 only have connections/roomClients only
> for 1 server, and have no information regarding second one.
>
>
> On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> *I see no other way to get the number of users (per server)*
>> => There are at least three alternative ways to get this number:
>> a) You count the number of connection of a certain scope and then take
>> the sum of it
>> This will give you the total number of connections, no matter if
>> audio/video, conferencing or a screensharing connection.
>> b) You count the total number of RoomClients from the current session
>> This will give you the total number of connections, no matter if
>> audio/video, conferencing or a screensharing connection.
>> c) You count the total number of RoomClients from the current session,
>> but you filter the result based on if the RoomClient is a Audio/Video
>> client or a Screensharing client
>> With this method you would be able to calc the exact number of
>> Audio/Video connection
>>
>> Which of those would fit yours?
>> Or did I misunderstood something?
>>
>> Sebastian
>>
>>
>> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>>
>>> Hello Sebastian,
>>>
>>> I'm afraid we need something like "lightweight RoomClient" in the DB to
>>> resolve 3)
>>> This can be done without performance degradation.
>>> I see no other way to get the number of users.
>>>
>>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> So will we find a consens here? :)
>>>>
>>>> 1) No DB query in Sync methods to keep performance up
>>>> 2) Session objects should not stay in a database but in memory
>>>> 3) To have the number of users per server instance there is no need to
>>>> have the RoomClient in the database.
>>>>
>>>> Can we find a consens based on those resolutions?
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>>
>>>> Practically in this case you would have to iterate thorugh the
>>>>> connection.
>>>>> You could also call IConnection => getConnection => getSize.
>>>>> This would give a rough idea. But as you don't know how many of those
>>>>> connection are screensharing or Audio/Video you can't tell how many users
>>>>> exactly there are.
>>>>>
>>>>> If you want to share this information with others I would suggest you
>>>>> simply add a SOAP/REST call and in that sense query the number of users via
>>>>> a HTTP call.
>>>>>
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> If I remember correctly I have added RoomClient to the DB since I
>>>>>> need mechanism to retrieve how much users are currently in the room.
>>>>>>
>>>>>>
>>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>>
>>>>>>> We will also stay with our Red5 implementation for the next 6 months
>>>>>>> as we have no alternative to stream audio/video in HTML5.
>>>>>>>
>>>>>>> It is no option to stay with it, how can we offer OpenMeetings to be
>>>>>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>>>>>>> it would become mandatory to have the database server on the same machine
>>>>>>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>>>>>>> imagine what kind of negative public feedback we will have if every
>>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>>> server on another instance of your network?
>>>>>>>
>>>>>>> Sorry but it is not possible. Also not for a temporary solution. We
>>>>>>> can't sell this product like that and claim to have 1000 user sessions per
>>>>>>> server unit.
>>>>>>>
>>>>>>> What requirements do exist to store the RoomClient in the database
>>>>>>> and what is needed to be done to remove it from the db again?
>>>>>>>
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>>> future.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> Sorry but:
>>>>>>>>>
>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>       return rc;
>>>>>>>>>    }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> That is simply not true.
>>>>>>>>> There are _some_ implementations where it was needed that you need
>>>>>>>>> to get the RoomClient by its public SID. However this usage was quite
>>>>>>>>> limited.
>>>>>>>>>
>>>>>>>>> In general it was the way I described it:
>>>>>>>>> The maps key was the streamid. And the streamid was obtained from
>>>>>>>>> the IConnection of each stream.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>>> Line 118, that was the function that was mainly in use all over
>>>>>>>>> the application.
>>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>>
>>>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" =>
>>>>>>>>> 52 of matches.
>>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>>> And if you iterate like described through all connection (like it
>>>>>>>>> is in EVERY snyc method)
>>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>>> Think about the green dot that blinks every time you speak in the
>>>>>>>>> video pod:
>>>>>>>>> If it gets visible => one sync message
>>>>>>>>> If its get transparent => one sync message.
>>>>>>>>> If you have a quite good and sensitive micro it will flush 10
>>>>>>>>> mabye 10 times per second.
>>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>>> SECOND
>>>>>>>>> => that is just impossible !!
>>>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every user
>>>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>>>> really?!
>>>>>>>>>
>>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> Previous solution was:
>>>>>>>>>>
>>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>>       return rc;
>>>>>>>>>>    }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>>> Right now we can filter all sessions with 1 query this is why the
>>>>>>>>>> code can work faster (after minor changes in iterating logic)
>>>>>>>>>>
>>>>>>>>>> I'm not insist RoomClient should be DB object. But having it as
>>>>>>>>>> DB object was the only option to have user count in the room (in case Rooms
>>>>>>>>>> are on the different servers).
>>>>>>>>>>
>>>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession
>>>>>>>>>> will be session object.
>>>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>
>>>>>>>>>>> you can't persist on the argumentation that a HashMap stored in
>>>>>>>>>>> the memory is slower then doing a single query for every entry of the map ?
>>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>>> map.get($streamId)
>>>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>>>
>>>>>>>>>>> I guess you had some other requirements that made you implement
>>>>>>>>>>> this.
>>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>>> However I also persist on my view:
>>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>>> performance in the future.
>>>>>>>>>>>
>>>>>>>>>>> Could you explain why there is a need for having the RoomClient
>>>>>>>>>>> in the database? Maybe we can resolve those requirements differently so
>>>>>>>>>>> that we can have the RoomClient back in memory.
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>>
>>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>>>> Current changes only make the calls faster (since DB is quered
>>>>>>>>>>>>> only once)
>>>>>>>>>>>>>
>>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map
>>>>>>>>>>>>> to get subset required.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up
>>>>>>>>>>>>> openjpa cache and if it doesn't help will split RoomClient to the couple of
>>>>>>>>>>>>> objects and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>>
>>>>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>>> How are we the in the future planning to determine the
>>>>>>>>>>>>>> current users in the room.
>>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I ask that critical as some queries require to sync messages
>>>>>>>>>>>>>> to all clients of a room.
>>>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> For example:
>>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Now the new thing is that for every connection you will
>>>>>>>>>>>>>> create a query for the RoomClient Object.
>>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>>>>>>> The RoomClient is a typical Session object and it should stay
>>>>>>>>>>>>>> in the session.
>>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>>> We are making a real time application, there is no chance to
>>>>>>>>>>>>>> run queries in sync methods.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Can we find some consens here? I know you must have
>>>>>>>>>>>>>> refactored already a lot but I strictly did implement zero db related stuff
>>>>>>>>>>>>>> in sync methods.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We calc the current users online by iterating through the
>>>>>>>>>>>>>>> Red5 Connections.
>>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT
>>>>>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER
>>>>>>>>>>>>>>>> BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId)
>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room
>>>>>>>>>>>>>>>> FROM Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted
>>>>>>>>>>>>>>>> = false "
>>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements
>>>>>>>>>>>>>>>> Serializab
>>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations
>>>>>>>>>>>>>>>> = new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>>> org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>>>>>> model) {
>>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>> DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType =
>>>>>>>>>>>>>>>> new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected")
>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> WBR
>>>>>>>>>> Maxim aka solomax
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
If there is only 1 server - all your solutions will work.
But imaging we have 2 servers. Each have its own room full of clients.

Now User enters server1 and would like to see how much users in each room.
But it is impossible since server1 only have connections/roomClients only
for 1 server, and have no information regarding second one.

On Wed, Oct 24, 2012 at 4:32 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> *I see no other way to get the number of users (per server)*
> => There are at least three alternative ways to get this number:
> a) You count the number of connection of a certain scope and then take the
> sum of it
> This will give you the total number of connections, no matter if
> audio/video, conferencing or a screensharing connection.
> b) You count the total number of RoomClients from the current session
> This will give you the total number of connections, no matter if
> audio/video, conferencing or a screensharing connection.
> c) You count the total number of RoomClients from the current session, but
> you filter the result based on if the RoomClient is a Audio/Video client or
> a Screensharing client
> With this method you would be able to calc the exact number of Audio/Video
> connection
>
> Which of those would fit yours?
> Or did I misunderstood something?
>
> Sebastian
>
>
> 2012/10/24 Maxim Solodovnik <so...@gmail.com>
>
>> Hello Sebastian,
>>
>> I'm afraid we need something like "lightweight RoomClient" in the DB to
>> resolve 3)
>> This can be done without performance degradation.
>> I see no other way to get the number of users.
>>
>> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> So will we find a consens here? :)
>>>
>>> 1) No DB query in Sync methods to keep performance up
>>> 2) Session objects should not stay in a database but in memory
>>> 3) To have the number of users per server instance there is no need to
>>> have the RoomClient in the database.
>>>
>>> Can we find a consens based on those resolutions?
>>>
>>> Sebastian
>>>
>>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>> Practically in this case you would have to iterate thorugh the
>>>> connection.
>>>> You could also call IConnection => getConnection => getSize.
>>>> This would give a rough idea. But as you don't know how many of those
>>>> connection are screensharing or Audio/Video you can't tell how many users
>>>> exactly there are.
>>>>
>>>> If you want to share this information with others I would suggest you
>>>> simply add a SOAP/REST call and in that sense query the number of users via
>>>> a HTTP call.
>>>>
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> If I remember correctly I have added RoomClient to the DB since I need
>>>>> mechanism to retrieve how much users are currently in the room.
>>>>>
>>>>>
>>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>
>>>>>> We will also stay with our Red5 implementation for the next 6 months
>>>>>> as we have no alternative to stream audio/video in HTML5.
>>>>>>
>>>>>> It is no option to stay with it, how can we offer OpenMeetings to be
>>>>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>>>>>> it would become mandatory to have the database server on the same machine
>>>>>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>>>>>> imagine what kind of negative public feedback we will have if every
>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>> server on another instance of your network?
>>>>>>
>>>>>> Sorry but it is not possible. Also not for a temporary solution. We
>>>>>> can't sell this product like that and claim to have 1000 user sessions per
>>>>>> server unit.
>>>>>>
>>>>>> What requirements do exist to store the RoomClient in the database
>>>>>> and what is needed to be done to remove it from the db again?
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>> future.
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> Sorry but:
>>>>>>>>
>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>       return rc;
>>>>>>>>    }
>>>>>>>> }
>>>>>>>>
>>>>>>>> That is simply not true.
>>>>>>>> There are _some_ implementations where it was needed that you need
>>>>>>>> to get the RoomClient by its public SID. However this usage was quite
>>>>>>>> limited.
>>>>>>>>
>>>>>>>> In general it was the way I described it:
>>>>>>>> The maps key was the streamid. And the streamid was obtained from
>>>>>>>> the IConnection of each stream.
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>> Line 118, that was the function that was mainly in use all over the
>>>>>>>> application.
>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>
>>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" =>
>>>>>>>> 52 of matches.
>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>> And if you iterate like described through all connection (like it
>>>>>>>> is in EVERY snyc method)
>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>> Think about the green dot that blinks every time you speak in the
>>>>>>>> video pod:
>>>>>>>> If it gets visible => one sync message
>>>>>>>> If its get transparent => one sync message.
>>>>>>>> If you have a quite good and sensitive micro it will flush 10 mabye
>>>>>>>> 10 times per second.
>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>> SECOND
>>>>>>>> => that is just impossible !!
>>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every user
>>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>>> really?!
>>>>>>>>
>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> Previous solution was:
>>>>>>>>>
>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>       return rc;
>>>>>>>>>    }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>> Right now we can filter all sessions with 1 query this is why the
>>>>>>>>> code can work faster (after minor changes in iterating logic)
>>>>>>>>>
>>>>>>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>>>>>>> object was the only option to have user count in the room (in case Rooms
>>>>>>>>> are on the different servers).
>>>>>>>>>
>>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession
>>>>>>>>> will be session object.
>>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Maxim,
>>>>>>>>>>
>>>>>>>>>> you can't persist on the argumentation that a HashMap stored in
>>>>>>>>>> the memory is slower then doing a single query for every entry of the map ?
>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>> map.get($streamId)
>>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>>
>>>>>>>>>> I guess you had some other requirements that made you implement
>>>>>>>>>> this.
>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>> However I also persist on my view:
>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot of
>>>>>>>>>> performance in the future.
>>>>>>>>>>
>>>>>>>>>> Could you explain why there is a need for having the RoomClient
>>>>>>>>>> in the database? Maybe we can resolve those requirements differently so
>>>>>>>>>> that we can have the RoomClient back in memory.
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>
>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>> solomax666@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>>> Current changes only make the calls faster (since DB is quered
>>>>>>>>>>>> only once)
>>>>>>>>>>>>
>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>
>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map to
>>>>>>>>>>>> get subset required.
>>>>>>>>>>>>
>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>>>>>>> cache and if it doesn't help will split RoomClient to the couple of objects
>>>>>>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>
>>>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>
>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>>>>>>> users in the room.
>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>
>>>>>>>>>>>>> I ask that critical as some queries require to sync messages
>>>>>>>>>>>>> to all clients of a room.
>>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>
>>>>>>>>>>>>> For example:
>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Now the new thing is that for every connection you will create
>>>>>>>>>>>>> a query for the RoomClient Object.
>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>
>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>>>>>> The RoomClient is a typical Session object and it should stay
>>>>>>>>>>>>> in the session.
>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>> We are making a real time application, there is no chance to
>>>>>>>>>>>>> run queries in sync methods.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>>>>>>>> methods.
>>>>>>>>>>>>>
>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>
>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We calc the current users online by iterating through the
>>>>>>>>>>>>>> Red5 Connections.
>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT
>>>>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER
>>>>>>>>>>>>>>> BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted
>>>>>>>>>>>>>>> = false "
>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations =
>>>>>>>>>>>>>>> new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>>>>> model) {
>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType =
>>>>>>>>>>>>>>> new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> <td><textarea wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
*I see no other way to get the number of users (per server)*
=> There are at least three alternative ways to get this number:
a) You count the number of connection of a certain scope and then take the
sum of it
This will give you the total number of connections, no matter if
audio/video, conferencing or a screensharing connection.
b) You count the total number of RoomClients from the current session
This will give you the total number of connections, no matter if
audio/video, conferencing or a screensharing connection.
c) You count the total number of RoomClients from the current session, but
you filter the result based on if the RoomClient is a Audio/Video client or
a Screensharing client
With this method you would be able to calc the exact number of Audio/Video
connection

Which of those would fit yours?
Or did I misunderstood something?

Sebastian

2012/10/24 Maxim Solodovnik <so...@gmail.com>

> Hello Sebastian,
>
> I'm afraid we need something like "lightweight RoomClient" in the DB to
> resolve 3)
> This can be done without performance degradation.
> I see no other way to get the number of users.
>
> On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> So will we find a consens here? :)
>>
>> 1) No DB query in Sync methods to keep performance up
>> 2) Session objects should not stay in a database but in memory
>> 3) To have the number of users per server instance there is no need to
>> have the RoomClient in the database.
>>
>> Can we find a consens based on those resolutions?
>>
>> Sebastian
>>
>> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>>
>> Practically in this case you would have to iterate thorugh the connection.
>>> You could also call IConnection => getConnection => getSize.
>>> This would give a rough idea. But as you don't know how many of those
>>> connection are screensharing or Audio/Video you can't tell how many users
>>> exactly there are.
>>>
>>> If you want to share this information with others I would suggest you
>>> simply add a SOAP/REST call and in that sense query the number of users via
>>> a HTTP call.
>>>
>>>
>>> Sebastian
>>>
>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> If I remember correctly I have added RoomClient to the DB since I need
>>>> mechanism to retrieve how much users are currently in the room.
>>>>
>>>>
>>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> We could even store it currently in the IConnection. The Red5
>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>
>>>>> We will also stay with our Red5 implementation for the next 6 months
>>>>> as we have no alternative to stream audio/video in HTML5.
>>>>>
>>>>> It is no option to stay with it, how can we offer OpenMeetings to be
>>>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>>>>> it would become mandatory to have the database server on the same machine
>>>>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>>>>> imagine what kind of negative public feedback we will have if every
>>>>> question about performance of red5 is answered with: Did you install db
>>>>> server on another instance of your network?
>>>>>
>>>>> Sorry but it is not possible. Also not for a temporary solution. We
>>>>> can't sell this product like that and claim to have 1000 user sessions per
>>>>> server unit.
>>>>>
>>>>> What requirements do exist to store the RoomClient in the database and
>>>>> what is needed to be done to remove it from the db again?
>>>>>
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>> future.
>>>>>>
>>>>>>
>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> Sorry but:
>>>>>>>
>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>       return rc;
>>>>>>>    }
>>>>>>> }
>>>>>>>
>>>>>>> That is simply not true.
>>>>>>> There are _some_ implementations where it was needed that you need
>>>>>>> to get the RoomClient by its public SID. However this usage was quite
>>>>>>> limited.
>>>>>>>
>>>>>>> In general it was the way I described it:
>>>>>>> The maps key was the streamid. And the streamid was obtained from
>>>>>>> the IConnection of each stream.
>>>>>>>
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>> Line 118, that was the function that was mainly in use all over the
>>>>>>> application.
>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>
>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" =>
>>>>>>> 52 of matches.
>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>> And if you iterate like described through all connection (like it is
>>>>>>> in EVERY snyc method)
>>>>>>> You will do a single query for EVERY connection.
>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>> Think about the green dot that blinks every time you speak in the
>>>>>>> video pod:
>>>>>>> If it gets visible => one sync message
>>>>>>> If its get transparent => one sync message.
>>>>>>> If you have a quite good and sensitive micro it will flush 10 mabye
>>>>>>> 10 times per second.
>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
>>>>>>> => that is just impossible !!
>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every user
>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>> really?!
>>>>>>>
>>>>>>> Sorry we will not follow that route :)
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> Previous solution was:
>>>>>>>>
>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>       return rc;
>>>>>>>>    }
>>>>>>>> }
>>>>>>>>
>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>> Right now we can filter all sessions with 1 query this is why the
>>>>>>>> code can work faster (after minor changes in iterating logic)
>>>>>>>>
>>>>>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>>>>>> object was the only option to have user count in the room (in case Rooms
>>>>>>>> are on the different servers).
>>>>>>>>
>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession will
>>>>>>>> be session object.
>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>
>>>>>>>>
>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> Hi Maxim,
>>>>>>>>>
>>>>>>>>> you can't persist on the argumentation that a HashMap stored in
>>>>>>>>> the memory is slower then doing a single query for every entry of the map ?
>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>> map.get($streamId)
>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>
>>>>>>>>> I guess you had some other requirements that made you implement
>>>>>>>>> this.
>>>>>>>>> For example for the clustering solution.
>>>>>>>>> However I also persist on my view:
>>>>>>>>> A database is _not_ the right place for storing session variables.
>>>>>>>>> This is simply a bad design decision that will cost a lot of performance in
>>>>>>>>> the future.
>>>>>>>>>
>>>>>>>>> Could you explain why there is a need for having the RoomClient in
>>>>>>>>> the database? Maybe we can resolve those requirements differently so that
>>>>>>>>> we can have the RoomClient back in memory.
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>>
>>>>>>>>>> Sorry for double post.
>>>>>>>>>>
>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>> Current changes only make the calls faster (since DB is quered
>>>>>>>>>>> only once)
>>>>>>>>>>>
>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>
>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map to
>>>>>>>>>>> get subset required.
>>>>>>>>>>>
>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>>>>>> cache and if it doesn't help will split RoomClient to the couple of objects
>>>>>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>
>>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>
>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>>>>>> users in the room.
>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>
>>>>>>>>>>>> I ask that critical as some queries require to sync messages to
>>>>>>>>>>>> all clients of a room.
>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>
>>>>>>>>>>>> For example:
>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>
>>>>>>>>>>>> Now the new thing is that for every connection you will create
>>>>>>>>>>>> a query for the RoomClient Object.
>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>
>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>>>>> The RoomClient is a typical Session object and it should stay
>>>>>>>>>>>> in the session.
>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>> We are making a real time application, there is no chance to
>>>>>>>>>>>> run queries in sync methods.
>>>>>>>>>>>>
>>>>>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>>>>>>> methods.
>>>>>>>>>>>>
>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>
>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>
>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>
>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>
>>>>>>>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>>>>>>>> Connections.
>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>
>>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>>
>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT
>>>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER
>>>>>>>>>>>>>> BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted =
>>>>>>>>>>>>>> false "
>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations =
>>>>>>>>>>>>>> new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>>>> model) {
>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType =
>>>>>>>>>>>>>> new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>> {
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>> -
>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>> -
>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>> -
>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>> +                                               <td><textarea
>>>>>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> WBR
>>>>>>>> Maxim aka solomax
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
Hello Sebastian,

I'm afraid we need something like "lightweight RoomClient" in the DB to
resolve 3)
This can be done without performance degradation.
I see no other way to get the number of users.

On Wed, Oct 24, 2012 at 3:31 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> So will we find a consens here? :)
>
> 1) No DB query in Sync methods to keep performance up
> 2) Session objects should not stay in a database but in memory
> 3) To have the number of users per server instance there is no need to
> have the RoomClient in the database.
>
> Can we find a consens based on those resolutions?
>
> Sebastian
>
> 2012/10/22 seba.wagner@gmail.com <se...@gmail.com>
>
> Practically in this case you would have to iterate thorugh the connection.
>> You could also call IConnection => getConnection => getSize.
>> This would give a rough idea. But as you don't know how many of those
>> connection are screensharing or Audio/Video you can't tell how many users
>> exactly there are.
>>
>> If you want to share this information with others I would suggest you
>> simply add a SOAP/REST call and in that sense query the number of users via
>> a HTTP call.
>>
>>
>> Sebastian
>>
>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>
>>> If I remember correctly I have added RoomClient to the DB since I need
>>> mechanism to retrieve how much users are currently in the room.
>>>
>>>
>>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> We could even store it currently in the IConnection. The Red5 framework
>>>> has the similar mechanism like the static Map that I've build.
>>>>
>>>> We will also stay with our Red5 implementation for the next 6 months as
>>>> we have no alternative to stream audio/video in HTML5.
>>>>
>>>> It is no option to stay with it, how can we offer OpenMeetings to be
>>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>>>> it would become mandatory to have the database server on the same machine
>>>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>>>> imagine what kind of negative public feedback we will have if every
>>>> question about performance of red5 is answered with: Did you install db
>>>> server on another instance of your network?
>>>>
>>>> Sorry but it is not possible. Also not for a temporary solution. We
>>>> can't sell this product like that and claim to have 1000 user sessions per
>>>> server unit.
>>>>
>>>> What requirements do exist to store the RoomClient in the database and
>>>> what is needed to be done to remove it from the db again?
>>>>
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> OK, I'm not insist. I believe RoomClient will be removed in the future.
>>>>>
>>>>>
>>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> Sorry but:
>>>>>>
>>>>>> for (RoomClient rc: allClient) {
>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>       return rc;
>>>>>>    }
>>>>>> }
>>>>>>
>>>>>> That is simply not true.
>>>>>> There are _some_ implementations where it was needed that you need to
>>>>>> get the RoomClient by its public SID. However this usage was quite limited.
>>>>>>
>>>>>> In general it was the way I described it:
>>>>>> The maps key was the streamid. And the streamid was obtained from the
>>>>>> IConnection of each stream.
>>>>>>
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>> Line 118, that was the function that was mainly in use all over the
>>>>>> application.
>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>
>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52
>>>>>> of matches.
>>>>>> Every of this call is now replaced by a single DB query.
>>>>>> And if you iterate like described through all connection (like it is
>>>>>> in EVERY snyc method)
>>>>>> You will do a single query for EVERY connection.
>>>>>> Like 100 users in a room => 100 queries.
>>>>>> Think about the green dot that blinks every time you speak in the
>>>>>> video pod:
>>>>>> If it gets visible => one sync message
>>>>>> If its get transparent => one sync message.
>>>>>> If you have a quite good and sensitive micro it will flush 10 mabye
>>>>>> 10 times per second.
>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
>>>>>> => that is just impossible !!
>>>>>> And that is just a SINGLE videopod with 100 users watching. Now scale
>>>>>> that up to 1000 concurrent rooms with  4x4 meetings where every user has
>>>>>> micro turned on ?! Should we calc the number of database queries really?!
>>>>>>
>>>>>> Sorry we will not follow that route :)
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> Previous solution was:
>>>>>>>
>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>       return rc;
>>>>>>>    }
>>>>>>> }
>>>>>>>
>>>>>>> + screen sharing clients were filtered same way.
>>>>>>> Right now we can filter all sessions with 1 query this is why the
>>>>>>> code can work faster (after minor changes in iterating logic)
>>>>>>>
>>>>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>>>>> object was the only option to have user count in the room (in case Rooms
>>>>>>> are on the different servers).
>>>>>>>
>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession will
>>>>>>> be session object.
>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> Hi Maxim,
>>>>>>>>
>>>>>>>> you can't persist on the argumentation that a HashMap stored in the
>>>>>>>> memory is slower then doing a single query for every entry of the map ?
>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>> map.get($streamId)
>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>>> faster or the same as previous one." :)
>>>>>>>>
>>>>>>>> I guess you had some other requirements that made you implement
>>>>>>>> this.
>>>>>>>> For example for the clustering solution.
>>>>>>>> However I also persist on my view:
>>>>>>>> A database is _not_ the right place for storing session variables.
>>>>>>>> This is simply a bad design decision that will cost a lot of performance in
>>>>>>>> the future.
>>>>>>>>
>>>>>>>> Could you explain why there is a need for having the RoomClient in
>>>>>>>> the database? Maybe we can resolve those requirements differently so that
>>>>>>>> we can have the RoomClient back in memory.
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>>
>>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>>
>>>>>>>>> Sorry for double post.
>>>>>>>>>
>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>> Current changes only make the calls faster (since DB is quered
>>>>>>>>>> only once)
>>>>>>>>>>
>>>>>>>>>> I'll try to create couple of tests. Right now I think the current
>>>>>>>>>> code should work faster or the same as previous one.
>>>>>>>>>>
>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map to
>>>>>>>>>> get subset required.
>>>>>>>>>>
>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>>>>> cache and if it doesn't help will split RoomClient to the couple of objects
>>>>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>
>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>
>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>>>>> users in the room.
>>>>>>>>>>> Session or database based?
>>>>>>>>>>>
>>>>>>>>>>> I ask that critical as some queries require to sync messages to
>>>>>>>>>>> all clients of a room.
>>>>>>>>>>> This can happen 1000 times in a single second if you think about
>>>>>>>>>>> having up to 1000 concurrent user sessions.
>>>>>>>>>>>
>>>>>>>>>>> For example:
>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>> current.getScope()
>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>
>>>>>>>>>>> Now the new thing is that for every connection you will create a
>>>>>>>>>>> query for the RoomClient Object.
>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>
>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>>>> The RoomClient is a typical Session object and it should stay in
>>>>>>>>>>> the session.
>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>> We are making a real time application, there is no chance to run
>>>>>>>>>>> queries in sync methods.
>>>>>>>>>>>
>>>>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>>>>>> methods.
>>>>>>>>>>>
>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>
>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>>
>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>
>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>
>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>
>>>>>>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>>>>>>> Connections.
>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>
>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>
>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>>
>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>
>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>> Log:
>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>
>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>
>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>> URL:
>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>
>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>> ---
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>> (original)
>>>>>>>>>>>>> +++
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>         }
>>>>>>>>>>>>>
>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT
>>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER
>>>>>>>>>>>>> BY r.name ASC", Rooms.class);
>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>> +       }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted =
>>>>>>>>>>>>> false "
>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>> +       }
>>>>>>>>>>>>> +
>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>
>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>> URL:
>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>
>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>> ---
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>> (original)
>>>>>>>>>>>>> +++
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>
>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>
>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations =
>>>>>>>>>>>>> new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>
>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>> -        */
>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>
>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>
>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>> URL:
>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>
>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>> ---
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>> (original)
>>>>>>>>>>>>> +++
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>   */
>>>>>>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>
>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +import
>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>  import
>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>> +import
>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>> +import
>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>> +import
>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>> +import
>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>
>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>
>>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>>> model) {
>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>>
>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>> +
>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>> +               });
>>>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>> +
>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>> +
>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>> +               });
>>>>>>>>>>>>> +       }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>> +               return
>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>> +       }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>> {
>>>>>>>>>>>>> +
>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>> +               }
>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>>>>>>>> +               }
>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>         }
>>>>>>>>>>>>>  }
>>>>>>>>>>>>>
>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>> URL:
>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>
>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>> ---
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>> (original)
>>>>>>>>>>>>> +++
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>> -
>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>> -
>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>> +
>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>> +
>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>
>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>> +                                               <td><textarea
>>>>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" wicket:id="save"
>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>> URL:
>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>
>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>> ---
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>> (original)
>>>>>>>>>>>>> +++
>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>
>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>
>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>> +
>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>
>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>
>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
So will we find a consens here? :)

1) No DB query in Sync methods to keep performance up
2) Session objects should not stay in a database but in memory
3) To have the number of users per server instance there is no need to have
the RoomClient in the database.

Can we find a consens based on those resolutions?

Sebastian

2012/10/22 seba.wagner@gmail.com <se...@gmail.com>

> Practically in this case you would have to iterate thorugh the connection.
> You could also call IConnection => getConnection => getSize.
> This would give a rough idea. But as you don't know how many of those
> connection are screensharing or Audio/Video you can't tell how many users
> exactly there are.
>
> If you want to share this information with others I would suggest you
> simply add a SOAP/REST call and in that sense query the number of users via
> a HTTP call.
>
>
> Sebastian
>
> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>
>> If I remember correctly I have added RoomClient to the DB since I need
>> mechanism to retrieve how much users are currently in the room.
>>
>>
>> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> We could even store it currently in the IConnection. The Red5 framework
>>> has the similar mechanism like the static Map that I've build.
>>>
>>> We will also stay with our Red5 implementation for the next 6 months as
>>> we have no alternative to stream audio/video in HTML5.
>>>
>>> It is no option to stay with it, how can we offer OpenMeetings to be
>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>>> it would become mandatory to have the database server on the same machine
>>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>>> imagine what kind of negative public feedback we will have if every
>>> question about performance of red5 is answered with: Did you install db
>>> server on another instance of your network?
>>>
>>> Sorry but it is not possible. Also not for a temporary solution. We
>>> can't sell this product like that and claim to have 1000 user sessions per
>>> server unit.
>>>
>>> What requirements do exist to store the RoomClient in the database and
>>> what is needed to be done to remove it from the db again?
>>>
>>>
>>> Sebastian
>>>
>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> OK, I'm not insist. I believe RoomClient will be removed in the future.
>>>>
>>>>
>>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> Sorry but:
>>>>>
>>>>> for (RoomClient rc: allClient) {
>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>       return rc;
>>>>>    }
>>>>> }
>>>>>
>>>>> That is simply not true.
>>>>> There are _some_ implementations where it was needed that you need to
>>>>> get the RoomClient by its public SID. However this usage was quite limited.
>>>>>
>>>>> In general it was the way I described it:
>>>>> The maps key was the streamid. And the streamid was obtained from the
>>>>> IConnection of each stream.
>>>>>
>>>>>
>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>> Line 118, that was the function that was mainly in use all over the
>>>>> application.
>>>>> There is no sorting, there is no iteration => nothing.
>>>>>
>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52
>>>>> of matches.
>>>>> Every of this call is now replaced by a single DB query.
>>>>> And if you iterate like described through all connection (like it is
>>>>> in EVERY snyc method)
>>>>> You will do a single query for EVERY connection.
>>>>> Like 100 users in a room => 100 queries.
>>>>> Think about the green dot that blinks every time you speak in the
>>>>> video pod:
>>>>> If it gets visible => one sync message
>>>>> If its get transparent => one sync message.
>>>>> If you have a quite good and sensitive micro it will flush 10 mabye 10
>>>>> times per second.
>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
>>>>> => that is just impossible !!
>>>>> And that is just a SINGLE videopod with 100 users watching. Now scale
>>>>> that up to 1000 concurrent rooms with  4x4 meetings where every user has
>>>>> micro turned on ?! Should we calc the number of database queries really?!
>>>>>
>>>>> Sorry we will not follow that route :)
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> Previous solution was:
>>>>>>
>>>>>> for (RoomClient rc: allClient) {
>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>       return rc;
>>>>>>    }
>>>>>> }
>>>>>>
>>>>>> + screen sharing clients were filtered same way.
>>>>>> Right now we can filter all sessions with 1 query this is why the
>>>>>> code can work faster (after minor changes in iterating logic)
>>>>>>
>>>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>>>> object was the only option to have user count in the room (in case Rooms
>>>>>> are on the different servers).
>>>>>>
>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession will
>>>>>> be session object.
>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>
>>>>>>
>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> Hi Maxim,
>>>>>>>
>>>>>>> you can't persist on the argumentation that a HashMap stored in the
>>>>>>> memory is slower then doing a single query for every entry of the map ?
>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>> Getting a RoomClient from this map was:
>>>>>>> map.get($streamId)
>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>>> How can you say that a "Right now I think the current code should work
>>>>>>> faster or the same as previous one." :)
>>>>>>>
>>>>>>> I guess you had some other requirements that made you implement this.
>>>>>>> For example for the clustering solution.
>>>>>>> However I also persist on my view:
>>>>>>> A database is _not_ the right place for storing session variables.
>>>>>>> This is simply a bad design decision that will cost a lot of performance in
>>>>>>> the future.
>>>>>>>
>>>>>>> Could you explain why there is a need for having the RoomClient in
>>>>>>> the database? Maybe we can resolve those requirements differently so that
>>>>>>> we can have the RoomClient back in memory.
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>>
>>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>>
>>>>>>>> Sorry for double post.
>>>>>>>>
>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>> Current changes only make the calls faster (since DB is quered
>>>>>>>>> only once)
>>>>>>>>>
>>>>>>>>> I'll try to create couple of tests. Right now I think the current
>>>>>>>>> code should work faster or the same as previous one.
>>>>>>>>>
>>>>>>>>> Old code did lots of full filterings of RommsClient hash map to
>>>>>>>>> get subset required.
>>>>>>>>>
>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>>>> cache and if it doesn't help will split RoomClient to the couple of objects
>>>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>>>
>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>
>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>>>> users in the room.
>>>>>>>>>> Session or database based?
>>>>>>>>>>
>>>>>>>>>> I ask that critical as some queries require to sync messages to
>>>>>>>>>> all clients of a room.
>>>>>>>>>> This can happen 1000 times in a single second if you think about
>>>>>>>>>> having up to 1000 concurrent user sessions.
>>>>>>>>>>
>>>>>>>>>> For example:
>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>>>>>>>                     .getConnections();
>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>
>>>>>>>>>> Now the new thing is that for every connection you will create a
>>>>>>>>>> query for the RoomClient Object.
>>>>>>>>>> This is simply impossible.
>>>>>>>>>>
>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>>> The RoomClient is a typical Session object and it should stay in
>>>>>>>>>> the session.
>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>> We are making a real time application, there is no chance to run
>>>>>>>>>> queries in sync methods.
>>>>>>>>>>
>>>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>>>>> methods.
>>>>>>>>>>
>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>
>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>>
>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>
>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>
>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>
>>>>>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>>>>>> Connections.
>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>
>>>>>>>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>>>>>>>> annotate it with:
>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>
>>>>>>>>>>> Sebastian
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>>
>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>
>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>> Log:
>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>
>>>>>>>>>>>> Modified:
>>>>>>>>>>>>
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>
>>>>>>>>>>>> Modified:
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>> URL:
>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>
>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>> ---
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>> (original)
>>>>>>>>>>>> +++
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>         }
>>>>>>>>>>>>
>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT
>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER
>>>>>>>>>>>> BY r.name ASC", Rooms.class);
>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>> +       }
>>>>>>>>>>>> +
>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>> :orgId "
>>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted =
>>>>>>>>>>>> false "
>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>> +       }
>>>>>>>>>>>> +
>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>
>>>>>>>>>>>> Modified:
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>> URL:
>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>
>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>> ---
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>> (original)
>>>>>>>>>>>> +++
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>
>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>
>>>>>>>>>>>>         @Lob
>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations =
>>>>>>>>>>>> new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>
>>>>>>>>>>>> -       /*
>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>> -        */
>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>
>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>
>>>>>>>>>>>> Modified:
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>> URL:
>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>
>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>> ---
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>> (original)
>>>>>>>>>>>> +++
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>   */
>>>>>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>
>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>> +
>>>>>>>>>>>> +import
>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>  import
>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>> +import
>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>> +import
>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>> +import
>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>
>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>
>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>> model) {
>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>
>>>>>>>>>>>>                 add(new
>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>                 add(new
>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>> +               add(new
>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>> +
>>>>>>>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>> +                               ,
>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>> +                               , new
>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>> +
>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>> +                               ,
>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>> +                               , new
>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>> +
>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>> +                               , new
>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>> +
>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>> +
>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>> +
>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>>> +                       }
>>>>>>>>>>>> +               });
>>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>> +
>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>> +
>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>> +
>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>> +                       }
>>>>>>>>>>>> +               });
>>>>>>>>>>>> +       }
>>>>>>>>>>>> +
>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>> +               return
>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>> +       }
>>>>>>>>>>>> +
>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>> {
>>>>>>>>>>>> +
>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>> +               }
>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>>>>>>> +               }
>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>         }
>>>>>>>>>>>>  }
>>>>>>>>>>>>
>>>>>>>>>>>> Modified:
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>> URL:
>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>
>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>> ---
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>> (original)
>>>>>>>>>>>> +++
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>                                 });
>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>> -
>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>> -
>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>> +
>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>> +
>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>
>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>> +                                               <td><textarea
>>>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>                                                 <td colspan="2"
>>>>>>>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>>>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>
>>>>>>>>>>>> Modified:
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>> URL:
>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>
>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>> ---
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>> (original)
>>>>>>>>>>>> +++
>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>
>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>
>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>> +
>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>> +                               }
>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>
>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>
>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> WBR
>>>>>> Maxim aka solomax
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
Practically in this case you would have to iterate thorugh the connection.
You could also call IConnection => getConnection => getSize.
This would give a rough idea. But as you don't know how many of those
connection are screensharing or Audio/Video you can't tell how many users
exactly there are.

If you want to share this information with others I would suggest you
simply add a SOAP/REST call and in that sense query the number of users via
a HTTP call.

Sebastian

2012/10/22 Maxim Solodovnik <so...@gmail.com>

> If I remember correctly I have added RoomClient to the DB since I need
> mechanism to retrieve how much users are currently in the room.
>
>
> On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> We could even store it currently in the IConnection. The Red5 framework
>> has the similar mechanism like the static Map that I've build.
>>
>> We will also stay with our Red5 implementation for the next 6 months as
>> we have no alternative to stream audio/video in HTML5.
>>
>> It is no option to stay with it, how can we offer OpenMeetings to be
>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>> it would become mandatory to have the database server on the same machine
>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>> imagine what kind of negative public feedback we will have if every
>> question about performance of red5 is answered with: Did you install db
>> server on another instance of your network?
>>
>> Sorry but it is not possible. Also not for a temporary solution. We can't
>> sell this product like that and claim to have 1000 user sessions per server
>> unit.
>>
>> What requirements do exist to store the RoomClient in the database and
>> what is needed to be done to remove it from the db again?
>>
>>
>> Sebastian
>>
>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>
>>> OK, I'm not insist. I believe RoomClient will be removed in the future.
>>>
>>>
>>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> Sorry but:
>>>>
>>>> for (RoomClient rc: allClient) {
>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>       return rc;
>>>>    }
>>>> }
>>>>
>>>> That is simply not true.
>>>> There are _some_ implementations where it was needed that you need to
>>>> get the RoomClient by its public SID. However this usage was quite limited.
>>>>
>>>> In general it was the way I described it:
>>>> The maps key was the streamid. And the streamid was obtained from the
>>>> IConnection of each stream.
>>>>
>>>>
>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>> Line 118, that was the function that was mainly in use all over the
>>>> application.
>>>> There is no sorting, there is no iteration => nothing.
>>>>
>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52
>>>> of matches.
>>>> Every of this call is now replaced by a single DB query.
>>>> And if you iterate like described through all connection (like it is in
>>>> EVERY snyc method)
>>>> You will do a single query for EVERY connection.
>>>> Like 100 users in a room => 100 queries.
>>>> Think about the green dot that blinks every time you speak in the video
>>>> pod:
>>>> If it gets visible => one sync message
>>>> If its get transparent => one sync message.
>>>> If you have a quite good and sensitive micro it will flush 10 mabye 10
>>>> times per second.
>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
>>>> => that is just impossible !!
>>>> And that is just a SINGLE videopod with 100 users watching. Now scale
>>>> that up to 1000 concurrent rooms with  4x4 meetings where every user has
>>>> micro turned on ?! Should we calc the number of database queries really?!
>>>>
>>>> Sorry we will not follow that route :)
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> Previous solution was:
>>>>>
>>>>> for (RoomClient rc: allClient) {
>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>       return rc;
>>>>>    }
>>>>> }
>>>>>
>>>>> + screen sharing clients were filtered same way.
>>>>> Right now we can filter all sessions with 1 query this is why the code
>>>>> can work faster (after minor changes in iterating logic)
>>>>>
>>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>>> object was the only option to have user count in the room (in case Rooms
>>>>> are on the different servers).
>>>>>
>>>>> I believe right now org.apache.openmeetings.web.app.WebSession will be
>>>>> session object.
>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>
>>>>>
>>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> Hi Maxim,
>>>>>>
>>>>>> you can't persist on the argumentation that a HashMap stored in the
>>>>>> memory is slower then doing a single query for every entry of the map ?
>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>> Getting a RoomClient from this map was:
>>>>>> map.get($streamId)
>>>>>> and now this single line is replaced by a Database query. The
>>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>>> How can you say that a "Right now I think the current code should work
>>>>>> faster or the same as previous one." :)
>>>>>>
>>>>>> I guess you had some other requirements that made you implement this.
>>>>>> For example for the clustering solution.
>>>>>> However I also persist on my view:
>>>>>> A database is _not_ the right place for storing session variables.
>>>>>> This is simply a bad design decision that will cost a lot of performance in
>>>>>> the future.
>>>>>>
>>>>>> Could you explain why there is a need for having the RoomClient in
>>>>>> the database? Maybe we can resolve those requirements differently so that
>>>>>> we can have the RoomClient back in memory.
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>>
>>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>>
>>>>>>> Sorry for double post.
>>>>>>>
>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>> Current changes only make the calls faster (since DB is quered only
>>>>>>>> once)
>>>>>>>>
>>>>>>>> I'll try to create couple of tests. Right now I think the current
>>>>>>>> code should work faster or the same as previous one.
>>>>>>>>
>>>>>>>> Old code did lots of full filterings of RommsClient hash map to get
>>>>>>>> subset required.
>>>>>>>>
>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>>> cache and if it doesn't help will split RoomClient to the couple of objects
>>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>>
>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>
>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>>> users in the room.
>>>>>>>>> Session or database based?
>>>>>>>>>
>>>>>>>>> I ask that critical as some queries require to sync messages to
>>>>>>>>> all clients of a room.
>>>>>>>>> This can happen 1000 times in a single second if you think about
>>>>>>>>> having up to 1000 concurrent user sessions.
>>>>>>>>>
>>>>>>>>> For example:
>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>>>>>>                     .getConnections();
>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>
>>>>>>>>> Now the new thing is that for every connection you will create a
>>>>>>>>> query for the RoomClient Object.
>>>>>>>>> This is simply impossible.
>>>>>>>>>
>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>> The RoomClient is a typical Session object and it should stay in
>>>>>>>>> the session.
>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>> We are making a real time application, there is no chance to run
>>>>>>>>> queries in sync methods.
>>>>>>>>>
>>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>>>> methods.
>>>>>>>>>
>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>
>>>>>>>>> What are you thoughts on this?
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>>
>>>>>>>>>> Hi Maxim,
>>>>>>>>>>
>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>
>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>
>>>>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>>>>> Connections.
>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>
>>>>>>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>>>>>>> annotate it with:
>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>>
>>>>>>>>>>  Author: solomax
>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>
>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>> Log:
>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>
>>>>>>>>>>> Modified:
>>>>>>>>>>>
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>
>>>>>>>>>>> Modified:
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>> URL:
>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>
>>>>>>>>>>> ==============================================================================
>>>>>>>>>>> ---
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>> (original)
>>>>>>>>>>> +++
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>         }
>>>>>>>>>>>
>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT JOIN
>>>>>>>>>>> FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>>>>>>>> r.name ASC", Rooms.class);
>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>> +       }
>>>>>>>>>>> +
>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id = :orgId
>>>>>>>>>>> "
>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted =
>>>>>>>>>>> false "
>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>> +       }
>>>>>>>>>>> +
>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>
>>>>>>>>>>> Modified:
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>> URL:
>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>
>>>>>>>>>>> ==============================================================================
>>>>>>>>>>> ---
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>> (original)
>>>>>>>>>>> +++
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>
>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>         private String name;
>>>>>>>>>>>
>>>>>>>>>>>         @Lob
>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>         private String comment;
>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>>>>>>>> ArrayList<Rooms_Organisation>();
>>>>>>>>>>>
>>>>>>>>>>> -       /*
>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>> -        */
>>>>>>>>>>> -       @Transient
>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>
>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>
>>>>>>>>>>> Modified:
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>> URL:
>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>
>>>>>>>>>>> ==============================================================================
>>>>>>>>>>> ---
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>> (original)
>>>>>>>>>>> +++
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>   */
>>>>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>
>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>> +
>>>>>>>>>>> +import
>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>  import
>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>> +import
>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>> +import
>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>> +import
>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>
>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>
>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>> model) {
>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>
>>>>>>>>>>>                 add(new
>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>                 add(new
>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>> +               add(new
>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>> +
>>>>>>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>> +                               "remind"
>>>>>>>>>>> +                               ,
>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>> +                               , new
>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>> +
>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>> +                               ,
>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>> +                               , new
>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>> +
>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>> +                               "room"
>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>> +                               , new
>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>> +               add(room);
>>>>>>>>>>> +
>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>> +                       private static final long
>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>> +
>>>>>>>>>>> +                       @Override
>>>>>>>>>>> +                       protected void
>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>> +                               createRoom = getConvertedInput();
>>>>>>>>>>> +
>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>>> +                       }
>>>>>>>>>>> +               });
>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>> +                       private static final long
>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>> +
>>>>>>>>>>> +                       @Override
>>>>>>>>>>> +                       protected void
>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>> +
>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>> +                       }
>>>>>>>>>>> +               });
>>>>>>>>>>> +       }
>>>>>>>>>>> +
>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>> +               return
>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>> +       }
>>>>>>>>>>> +
>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>> {
>>>>>>>>>>> +
>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>> +               }
>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>>>>>> +               }
>>>>>>>>>>> +               return result;
>>>>>>>>>>>         }
>>>>>>>>>>>  }
>>>>>>>>>>>
>>>>>>>>>>> Modified:
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>> URL:
>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>
>>>>>>>>>>> ==============================================================================
>>>>>>>>>>> ---
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>> (original)
>>>>>>>>>>> +++
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>                                 });
>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>>>>>> -                                               <td>
>>>>>>>>>>> -
>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>> -
>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>> -                                               </td>
>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>> +
>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>> +
>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>                                                 <td
>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>> -                                               <td
>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>> +                                               <td
>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>                                                 <td
>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>
>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>> +                                               <td><textarea
>>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>                                                 <td colspan="2"
>>>>>>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>                                 </table>
>>>>>>>>>>>                         </form>
>>>>>>>>>>>                 </div>
>>>>>>>>>>>
>>>>>>>>>>> Modified:
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>> URL:
>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>
>>>>>>>>>>> ==============================================================================
>>>>>>>>>>> ---
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>> (original)
>>>>>>>>>>> +++
>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>
>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>
>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>> +
>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>> +                               }
>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>> Appointment();
>>>>>>>>>>>
>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>
>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
If I remember correctly I have added RoomClient to the DB since I need
mechanism to retrieve how much users are currently in the room.

On Mon, Oct 22, 2012 at 3:23 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> We could even store it currently in the IConnection. The Red5 framework
> has the similar mechanism like the static Map that I've build.
>
> We will also stay with our Red5 implementation for the next 6 months as we
> have no alternative to stream audio/video in HTML5.
>
> It is no option to stay with it, how can we offer OpenMeetings to be
> scalable to 1000 concurrent users? We would have to limit it to 250. Also
> it would become mandatory to have the database server on the same machine
> as the red5 server. Otherwise you have performance bottlenecks. Can you
> imagine what kind of negative public feedback we will have if every
> question about performance of red5 is answered with: Did you install db
> server on another instance of your network?
>
> Sorry but it is not possible. Also not for a temporary solution. We can't
> sell this product like that and claim to have 1000 user sessions per server
> unit.
>
> What requirements do exist to store the RoomClient in the database and
> what is needed to be done to remove it from the db again?
>
>
> Sebastian
>
> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>
>> OK, I'm not insist. I believe RoomClient will be removed in the future.
>>
>>
>> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> Sorry but:
>>>
>>> for (RoomClient rc: allClient) {
>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>       return rc;
>>>    }
>>> }
>>>
>>> That is simply not true.
>>> There are _some_ implementations where it was needed that you need to
>>> get the RoomClient by its public SID. However this usage was quite limited.
>>>
>>> In general it was the way I described it:
>>> The maps key was the streamid. And the streamid was obtained from the
>>> IConnection of each stream.
>>>
>>>
>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>> Line 118, that was the function that was mainly in use all over the
>>> application.
>>> There is no sorting, there is no iteration => nothing.
>>>
>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52 of
>>> matches.
>>> Every of this call is now replaced by a single DB query.
>>> And if you iterate like described through all connection (like it is in
>>> EVERY snyc method)
>>> You will do a single query for EVERY connection.
>>> Like 100 users in a room => 100 queries.
>>> Think about the green dot that blinks every time you speak in the video
>>> pod:
>>> If it gets visible => one sync message
>>> If its get transparent => one sync message.
>>> If you have a quite good and sensitive micro it will flush 10 mabye 10
>>> times per second.
>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
>>> => that is just impossible !!
>>> And that is just a SINGLE videopod with 100 users watching. Now scale
>>> that up to 1000 concurrent rooms with  4x4 meetings where every user has
>>> micro turned on ?! Should we calc the number of database queries really?!
>>>
>>> Sorry we will not follow that route :)
>>>
>>> Sebastian
>>>
>>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> Previous solution was:
>>>>
>>>> for (RoomClient rc: allClient) {
>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>       return rc;
>>>>    }
>>>> }
>>>>
>>>> + screen sharing clients were filtered same way.
>>>> Right now we can filter all sessions with 1 query this is why the code
>>>> can work faster (after minor changes in iterating logic)
>>>>
>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>> object was the only option to have user count in the room (in case Rooms
>>>> are on the different servers).
>>>>
>>>> I believe right now org.apache.openmeetings.web.app.WebSession will be
>>>> session object.
>>>> I hope everything except audio and video will move to Wicket :)
>>>>
>>>>
>>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>>> seba.wagner@gmail.com> wrote:
>>>>
>>>>> Hi Maxim,
>>>>>
>>>>> you can't persist on the argumentation that a HashMap stored in the
>>>>> memory is slower then doing a single query for every entry of the map ?
>>>>> Basicaly the previous implementation was a single HashMap.
>>>>> Getting a RoomClient from this map was:
>>>>> map.get($streamId)
>>>>> and now this single line is replaced by a Database query. The
>>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>>> How can you say that a "Right now I think the current code should work
>>>>> faster or the same as previous one." :)
>>>>>
>>>>> I guess you had some other requirements that made you implement this.
>>>>> For example for the clustering solution.
>>>>> However I also persist on my view:
>>>>> A database is _not_ the right place for storing session variables.
>>>>> This is simply a bad design decision that will cost a lot of performance in
>>>>> the future.
>>>>>
>>>>> Could you explain why there is a need for having the RoomClient in the
>>>>> database? Maybe we can resolve those requirements differently so that we
>>>>> can have the RoomClient back in memory.
>>>>>
>>>>> Sebastian
>>>>>
>>>>>
>>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>>
>>>>>> Sorry for double post.
>>>>>>
>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>> export/import" is not necessary since it doesn't have @Element annotation
>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>> Current changes only make the calls faster (since DB is quered only
>>>>>>> once)
>>>>>>>
>>>>>>> I'll try to create couple of tests. Right now I think the current
>>>>>>> code should work faster or the same as previous one.
>>>>>>>
>>>>>>> Old code did lots of full filterings of RommsClient hash map to get
>>>>>>> subset required.
>>>>>>>
>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>> cache and if it doesn't help will split RoomClient to the couple of objects
>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>
>>>>>>> But I hope everything is not so slow since these changes are present
>>>>>>> in 2.0 and nobody reports performance degradation.
>>>>>>>
>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>>
>>>>>>>> I guess this happened lately in trunk.
>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>> users in the room.
>>>>>>>> Session or database based?
>>>>>>>>
>>>>>>>> I ask that critical as some queries require to sync messages to all
>>>>>>>> clients of a room.
>>>>>>>> This can happen 1000 times in a single second if you think about
>>>>>>>> having up to 1000 concurrent user sessions.
>>>>>>>>
>>>>>>>> For example:
>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>>>>>                     .getConnections();
>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>
>>>>>>>> Now the new thing is that for every connection you will create a
>>>>>>>> query for the RoomClient Object.
>>>>>>>> This is simply impossible.
>>>>>>>>
>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>> The RoomClient is a typical Session object and it should stay in
>>>>>>>> the session.
>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>> We are making a real time application, there is no chance to run
>>>>>>>> queries in sync methods.
>>>>>>>>
>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>>> methods.
>>>>>>>>
>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>>> time session, second time database) makes sense.
>>>>>>>>
>>>>>>>> What are you thoughts on this?
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>>
>>>>>>>>> Hi Maxim,
>>>>>>>>>
>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>
>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>
>>>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>>>> Connections.
>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>
>>>>>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>>>>>> annotate it with:
>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>> same like roomOrganisations.
>>>>>>>>>
>>>>>>>>> Sebastian
>>>>>>>>>
>>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>>
>>>>>>>>>  Author: solomax
>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>
>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>> Log:
>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>
>>>>>>>>>> Modified:
>>>>>>>>>>
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>
>>>>>>>>>> Modified:
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>> URL:
>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>
>>>>>>>>>> ==============================================================================
>>>>>>>>>> ---
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>> (original)
>>>>>>>>>> +++
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>         }
>>>>>>>>>>
>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>> +                               "SELECT r from Rooms r LEFT JOIN
>>>>>>>>>> FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>>>>>>> r.name ASC", Rooms.class);
>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>> +       }
>>>>>>>>>> +
>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>> c.room.currentusers "
>>>>>>>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted =
>>>>>>>>>> false "
>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>> +       }
>>>>>>>>>> +
>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>
>>>>>>>>>> Modified:
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>> URL:
>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>
>>>>>>>>>> ==============================================================================
>>>>>>>>>> ---
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>> (original)
>>>>>>>>>> +++
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>
>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>         private String name;
>>>>>>>>>>
>>>>>>>>>>         @Lob
>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>         private String comment;
>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>>>>>>> ArrayList<Rooms_Organisation>();
>>>>>>>>>>
>>>>>>>>>> -       /*
>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>> -        */
>>>>>>>>>> -       @Transient
>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>
>>>>>>>>>>         public String getComment() {
>>>>>>>>>>
>>>>>>>>>> Modified:
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>> URL:
>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>
>>>>>>>>>> ==============================================================================
>>>>>>>>>> ---
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>> (original)
>>>>>>>>>> +++
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>   */
>>>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>
>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>> +import java.util.List;
>>>>>>>>>> +
>>>>>>>>>> +import
>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>  import
>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>> +import
>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>> +import
>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>
>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>
>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment> model)
>>>>>>>>>> {
>>>>>>>>>>                 super(id, model);
>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>
>>>>>>>>>>                 add(new
>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>                 add(new
>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>> +               add(new TextField<String>("appointmentLocation"));
>>>>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>> +               add(pwd);
>>>>>>>>>> +
>>>>>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>> +                               "remind"
>>>>>>>>>> +                               ,
>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>> +                               , new
>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>> +
>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>> +                               ,
>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>> +                               , new
>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>> +               add(roomType);
>>>>>>>>>> +
>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>> +                               "room"
>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>> +                               , new
>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>> +               add(room);
>>>>>>>>>> +
>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>> +                       private static final long
>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>> +
>>>>>>>>>> +                       @Override
>>>>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>>>>> target) {
>>>>>>>>>> +                               createRoom = getConvertedInput();
>>>>>>>>>> +
>>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>>> +                       }
>>>>>>>>>> +               });
>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>> +                       private static final long
>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>> +
>>>>>>>>>> +                       @Override
>>>>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>>>>> target) {
>>>>>>>>>> +
>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>> +                       }
>>>>>>>>>> +               });
>>>>>>>>>> +       }
>>>>>>>>>> +
>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>> +               return
>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>> +       }
>>>>>>>>>> +
>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>> {
>>>>>>>>>> +
>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>> +               }
>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>>>>> +               }
>>>>>>>>>> +               return result;
>>>>>>>>>>         }
>>>>>>>>>>  }
>>>>>>>>>>
>>>>>>>>>> Modified:
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>> URL:
>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>
>>>>>>>>>> ==============================================================================
>>>>>>>>>> ---
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>> (original)
>>>>>>>>>> +++
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>                                         , resizable: true
>>>>>>>>>> -                                       , width: 400
>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>                                         , modal: true
>>>>>>>>>>                                 });
>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>                                                 <td><input
>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>>>>> -                                               <td>
>>>>>>>>>> -
>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>> -
>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>> -                                               </td>
>>>>>>>>>> +                                       <tr>
>>>>>>>>>> +
>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>> +                                               <td><span
>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>> +                                       </tr>
>>>>>>>>>> +                                       <tr>
>>>>>>>>>> +
>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>> +                                               <td><span
>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>> -                                               <td><select
>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>> +                                               <td><select
>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>                                                 <td
>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>> -                                               <td><select
>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>> +                                               <td><select
>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>                                                 <td><select
>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>> -                                               <td
>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>> +                                               <td
>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>> -                                               <td><input
>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>> +                                               <td><input
>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>                                                 <td
>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>> +                                       <!--
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>                                                 <td><select
>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>> -                                       </tr>
>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>                                                 <td><input
>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>> -                                       </tr-->
>>>>>>>>>> +                                       </tr>
>>>>>>>>>>                                         <tr>
>>>>>>>>>>
>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>> -                                               <td><input
>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>> +                                               <td><textarea
>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>                                         </tr>
>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>                                                 <td colspan="2"
>>>>>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>>>>>> -                                       </tr-->
>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>                                 </table>
>>>>>>>>>>                         </form>
>>>>>>>>>>                 </div>
>>>>>>>>>>
>>>>>>>>>> Modified:
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>> URL:
>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>
>>>>>>>>>> ==============================================================================
>>>>>>>>>> ---
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>> (original)
>>>>>>>>>> +++
>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>                                 Calendar end =
>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>
>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>
>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>> +
>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>> +                               }
>>>>>>>>>>                                 Appointment a = new Appointment();
>>>>>>>>>>
>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>
>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Sebastian Wagner
>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>> http://www.webbase-design.de
>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>> seba.wagner@gmail.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> WBR
>>>> Maxim aka solomax
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
We could even store it currently in the IConnection. The Red5 framework has
the similar mechanism like the static Map that I've build.

We will also stay with our Red5 implementation for the next 6 months as we
have no alternative to stream audio/video in HTML5.

It is no option to stay with it, how can we offer OpenMeetings to be
scalable to 1000 concurrent users? We would have to limit it to 250. Also
it would become mandatory to have the database server on the same machine
as the red5 server. Otherwise you have performance bottlenecks. Can you
imagine what kind of negative public feedback we will have if every
question about performance of red5 is answered with: Did you install db
server on another instance of your network?

Sorry but it is not possible. Also not for a temporary solution. We can't
sell this product like that and claim to have 1000 user sessions per server
unit.

What requirements do exist to store the RoomClient in the database and what
is needed to be done to remove it from the db again?

Sebastian

2012/10/22 Maxim Solodovnik <so...@gmail.com>

> OK, I'm not insist. I believe RoomClient will be removed in the future.
>
>
> On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> Sorry but:
>>
>> for (RoomClient rc: allClient) {
>>    if (rc.getPublicSID().equals(_publicSID) {
>>       return rc;
>>    }
>> }
>>
>> That is simply not true.
>> There are _some_ implementations where it was needed that you need to get
>> the RoomClient by its public SID. However this usage was quite limited.
>>
>> In general it was the way I described it:
>> The maps key was the streamid. And the streamid was obtained from the
>> IConnection of each stream.
>>
>>
>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>> Line 118, that was the function that was mainly in use all over the
>> application.
>> There is no sorting, there is no iteration => nothing.
>>
>> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52 of
>> matches.
>> Every of this call is now replaced by a single DB query.
>> And if you iterate like described through all connection (like it is in
>> EVERY snyc method)
>> You will do a single query for EVERY connection.
>> Like 100 users in a room => 100 queries.
>> Think about the green dot that blinks every time you speak in the video
>> pod:
>> If it gets visible => one sync message
>> If its get transparent => one sync message.
>> If you have a quite good and sensitive micro it will flush 10 mabye 10
>> times per second.
>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
>> => that is just impossible !!
>> And that is just a SINGLE videopod with 100 users watching. Now scale
>> that up to 1000 concurrent rooms with  4x4 meetings where every user has
>> micro turned on ?! Should we calc the number of database queries really?!
>>
>> Sorry we will not follow that route :)
>>
>> Sebastian
>>
>> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>>
>>> Previous solution was:
>>>
>>> for (RoomClient rc: allClient) {
>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>       return rc;
>>>    }
>>> }
>>>
>>> + screen sharing clients were filtered same way.
>>> Right now we can filter all sessions with 1 query this is why the code
>>> can work faster (after minor changes in iterating logic)
>>>
>>> I'm not insist RoomClient should be DB object. But having it as DB
>>> object was the only option to have user count in the room (in case Rooms
>>> are on the different servers).
>>>
>>> I believe right now org.apache.openmeetings.web.app.WebSession will be
>>> session object.
>>> I hope everything except audio and video will move to Wicket :)
>>>
>>>
>>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>>> seba.wagner@gmail.com> wrote:
>>>
>>>> Hi Maxim,
>>>>
>>>> you can't persist on the argumentation that a HashMap stored in the
>>>> memory is slower then doing a single query for every entry of the map ?
>>>> Basicaly the previous implementation was a single HashMap.
>>>> Getting a RoomClient from this map was:
>>>> map.get($streamId)
>>>> and now this single line is replaced by a Database query. The
>>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>>> How can you say that a "Right now I think the current code should work
>>>> faster or the same as previous one." :)
>>>>
>>>> I guess you had some other requirements that made you implement this.
>>>> For example for the clustering solution.
>>>> However I also persist on my view:
>>>> A database is _not_ the right place for storing session variables. This
>>>> is simply a bad design decision that will cost a lot of performance in the
>>>> future.
>>>>
>>>> Could you explain why there is a need for having the RoomClient in the
>>>> database? Maybe we can resolve those requirements differently so that we
>>>> can have the RoomClient back in memory.
>>>>
>>>> Sebastian
>>>>
>>>>
>>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>>
>>>>> Sorry for double post.
>>>>>
>>>>> Correct me if I'm wrong, but i think "Transient for XML export/import"
>>>>> is not necessary since it doesn't have @Element annotation
>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>> Current changes only make the calls faster (since DB is quered only
>>>>>> once)
>>>>>>
>>>>>> I'll try to create couple of tests. Right now I think the current
>>>>>> code should work faster or the same as previous one.
>>>>>>
>>>>>> Old code did lots of full filterings of RommsClient hash map to get
>>>>>> subset required.
>>>>>>
>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa cache
>>>>>> and if it doesn't help will split RoomClient to the couple of objects
>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>
>>>>>> But I hope everything is not so slow since these changes are present
>>>>>> in 2.0 and nobody reports performance degradation.
>>>>>>
>>>>>> Sorry for typos, I'm from mobile phone
>>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>>> seba.wagner@gmail.com> wrote:
>>>>>>
>>>>>>> I guess this happened lately in trunk.
>>>>>>> How are we the in the future planning to determine the current users
>>>>>>> in the room.
>>>>>>> Session or database based?
>>>>>>>
>>>>>>> I ask that critical as some queries require to sync messages to all
>>>>>>> clients of a room.
>>>>>>> This can happen 1000 times in a single second if you think about
>>>>>>> having up to 1000 concurrent user sessions.
>>>>>>>
>>>>>>> For example:
>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>>>>                     .getConnections();
>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>
>>>>>>> Now the new thing is that for every connection you will create a
>>>>>>> query for the RoomClient Object.
>>>>>>> This is simply impossible.
>>>>>>>
>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>> The RoomClient is a typical Session object and it should stay in the
>>>>>>> session.
>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>> We are making a real time application, there is no chance to run
>>>>>>> queries in sync methods.
>>>>>>>
>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>>> methods.
>>>>>>>
>>>>>>> There might be a chance for some events to trigger db
>>>>>>> actions.However I don't think having two times the RoomClient stored (one
>>>>>>> time session, second time database) makes sense.
>>>>>>>
>>>>>>> What are you thoughts on this?
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>>
>>>>>>>> Hi Maxim,
>>>>>>>>
>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>
>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>
>>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>>> Connections.
>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>
>>>>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>>>>> annotate it with:
>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>> same like roomOrganisations.
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>>
>>>>>>>>  Author: solomax
>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>> New Revision: 1400075
>>>>>>>>>
>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>> Log:
>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>>
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>> URL:
>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>         }
>>>>>>>>>
>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>> +                               "SELECT r from Rooms r LEFT JOIN
>>>>>>>>> FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>>>>>> r.name ASC", Rooms.class);
>>>>>>>>> +               return q.getResultList();
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>> c.room.currentusers "
>>>>>>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted =
>>>>>>>>> false "
>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>> +               return q.getResultList();
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>> *******************************************************************************/
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>> URL:
>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>
>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>         private String name;
>>>>>>>>>
>>>>>>>>>         @Lob
>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>         private String comment;
>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>>>>>> ArrayList<Rooms_Organisation>();
>>>>>>>>>
>>>>>>>>> -       /*
>>>>>>>>> -        * Non persistent attributes
>>>>>>>>> -        */
>>>>>>>>> -       @Transient
>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>
>>>>>>>>>         public String getComment() {
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>> URL:
>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>   */
>>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>
>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>> +import java.util.List;
>>>>>>>>> +
>>>>>>>>> +import
>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>  import
>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>> +import
>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>> +import
>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>
>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>> -1764738237821487526L;
>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>
>>>>>>>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>>>>>>>                 super(id, model);
>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>
>>>>>>>>>                 add(new
>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>                 add(new
>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>> +               add(new TextField<String>("appointmentLocation"));
>>>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>> PasswordTextField("password");
>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>> +               add(pwd);
>>>>>>>>> +
>>>>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>> +                               "remind"
>>>>>>>>> +                               ,
>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>> +                               , new
>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>> +
>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>>>> +                               "room.roomtype"
>>>>>>>>> +                               ,
>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>> +                               , new
>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>> +               add(roomType);
>>>>>>>>> +
>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>> +                               "room"
>>>>>>>>> +                               , getRoomList()
>>>>>>>>> +                               , new
>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>> +               add(room);
>>>>>>>>> +
>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>> +                       private static final long serialVersionUID
>>>>>>>>> = -3743113990890386035L;
>>>>>>>>> +
>>>>>>>>> +                       @Override
>>>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>>>> target) {
>>>>>>>>> +                               createRoom = getConvertedInput();
>>>>>>>>> +
>>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>>> +                       }
>>>>>>>>> +               });
>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>> +                       private static final long serialVersionUID
>>>>>>>>> = 6041200584296439976L;
>>>>>>>>> +
>>>>>>>>> +                       @Override
>>>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>>>> target) {
>>>>>>>>> +
>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>>>>>> +                               target.add(pwd);
>>>>>>>>> +                       }
>>>>>>>>> +               });
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>> +               return
>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>> {
>>>>>>>>> +
>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>> +               }
>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>>>> +               }
>>>>>>>>> +               return result;
>>>>>>>>>         }
>>>>>>>>>  }
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>> URL:
>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>                                         , resizable: true
>>>>>>>>> -                                       , width: 400
>>>>>>>>> +                                       , width: 450
>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>                                         , modal: true
>>>>>>>>>                                 });
>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>                                                 <td><input
>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>                                         </tr>
>>>>>>>>> -                                       <!-- tr>
>>>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>>>> -                                               <td>
>>>>>>>>> -
>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>> -
>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>> -                                               </td>
>>>>>>>>> +                                       <tr>
>>>>>>>>> +
>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>> +                                               <td><span
>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>> +                                       </tr>
>>>>>>>>> +                                       <tr>
>>>>>>>>> +
>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>> +                                               <td><span
>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>> -                                               <td><select
>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>> +                                               <td><select
>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>                                                 <td
>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>> -                                               <td><select
>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>> +                                               <td><select
>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>                                                 <td><select
>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>> -                                               <td
>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>> +                                               <td
>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>> -                                               <td><input
>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>> +                                               <td><input
>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>                                                 <td
>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>                                         </tr>
>>>>>>>>> +                                       <!--
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>                                                 <td><select
>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>> -                                       </tr>
>>>>>>>>> +                                       </tr -->
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>                                                 <td><input
>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>> -                                       </tr-->
>>>>>>>>> +                                       </tr>
>>>>>>>>>                                         <tr>
>>>>>>>>>
>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>> -                                               <td><input
>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>> +                                               <td><textarea
>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>                                         </tr>
>>>>>>>>>                                         <!-- tr>
>>>>>>>>>                                                 <td colspan="2"
>>>>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>>>>> -                                       </tr-->
>>>>>>>>> +                                       </tr -->
>>>>>>>>>                                 </table>
>>>>>>>>>                         </form>
>>>>>>>>>                 </div>
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>> URL:
>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>                                 Calendar end =
>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>
>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>
>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>> +
>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>> +                               }
>>>>>>>>>                                 Appointment a = new Appointment();
>>>>>>>>>
>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>
>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> seba.wagner@gmail.com
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>>
>>>>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> WBR
>>> Maxim aka solomax
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
OK, I'm not insist. I believe RoomClient will be removed in the future.


On Mon, Oct 22, 2012 at 3:00 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> Sorry but:
>
> for (RoomClient rc: allClient) {
>    if (rc.getPublicSID().equals(_publicSID) {
>       return rc;
>    }
> }
>
> That is simply not true.
> There are _some_ implementations where it was needed that you need to get
> the RoomClient by its public SID. However this usage was quite limited.
>
> In general it was the way I described it:
> The maps key was the streamid. And the streamid was obtained from the
> IConnection of each stream.
>
>
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
> Line 118, that was the function that was mainly in use all over the
> application.
> There is no sorting, there is no iteration => nothing.
>
> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52 of
> matches.
> Every of this call is now replaced by a single DB query.
> And if you iterate like described through all connection (like it is in
> EVERY snyc method)
> You will do a single query for EVERY connection.
> Like 100 users in a room => 100 queries.
> Think about the green dot that blinks every time you speak in the video
> pod:
> If it gets visible => one sync message
> If its get transparent => one sync message.
> If you have a quite good and sensitive micro it will flush 10 mabye 10
> times per second.
> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
> => that is just impossible !!
> And that is just a SINGLE videopod with 100 users watching. Now scale that
> up to 1000 concurrent rooms with  4x4 meetings where every user has micro
> turned on ?! Should we calc the number of database queries really?!
>
> Sorry we will not follow that route :)
>
> Sebastian
>
> 2012/10/22 Maxim Solodovnik <so...@gmail.com>
>
>> Previous solution was:
>>
>> for (RoomClient rc: allClient) {
>>    if (rc.getPublicSID().equals(_publicSID) {
>>       return rc;
>>    }
>> }
>>
>> + screen sharing clients were filtered same way.
>> Right now we can filter all sessions with 1 query this is why the code
>> can work faster (after minor changes in iterating logic)
>>
>> I'm not insist RoomClient should be DB object. But having it as DB object
>> was the only option to have user count in the room (in case Rooms are on
>> the different servers).
>>
>> I believe right now org.apache.openmeetings.web.app.WebSession will be
>> session object.
>> I hope everything except audio and video will move to Wicket :)
>>
>>
>> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
>> seba.wagner@gmail.com> wrote:
>>
>>> Hi Maxim,
>>>
>>> you can't persist on the argumentation that a HashMap stored in the
>>> memory is slower then doing a single query for every entry of the map ?
>>> Basicaly the previous implementation was a single HashMap.
>>> Getting a RoomClient from this map was:
>>> map.get($streamId)
>>> and now this single line is replaced by a Database query. The
>>> performance of this single line  is ... I guess smaller then 1 millisecond.
>>> How can you say that a "Right now I think the current code should work
>>> faster or the same as previous one." :)
>>>
>>> I guess you had some other requirements that made you implement this.
>>> For example for the clustering solution.
>>> However I also persist on my view:
>>> A database is _not_ the right place for storing session variables. This
>>> is simply a bad design decision that will cost a lot of performance in the
>>> future.
>>>
>>> Could you explain why there is a need for having the RoomClient in the
>>> database? Maybe we can resolve those requirements differently so that we
>>> can have the RoomClient back in memory.
>>>
>>> Sebastian
>>>
>>>
>>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>>
>>>> Sorry for double post.
>>>>
>>>> Correct me if I'm wrong, but i think "Transient for XML export/import"
>>>> is not necessary since it doesn't have @Element annotation
>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>>> wrote:
>>>>
>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>> Current changes only make the calls faster (since DB is quered only
>>>>> once)
>>>>>
>>>>> I'll try to create couple of tests. Right now I think the current code
>>>>> should work faster or the same as previous one.
>>>>>
>>>>> Old code did lots of full filterings of RommsClient hash map to get
>>>>> subset required.
>>>>>
>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa cache
>>>>> and if it doesn't help will split RoomClient to the couple of objects
>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>
>>>>> But I hope everything is not so slow since these changes are present
>>>>> in 2.0 and nobody reports performance degradation.
>>>>>
>>>>> Sorry for typos, I'm from mobile phone
>>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <
>>>>> seba.wagner@gmail.com> wrote:
>>>>>
>>>>>> I guess this happened lately in trunk.
>>>>>> How are we the in the future planning to determine the current users
>>>>>> in the room.
>>>>>> Session or database based?
>>>>>>
>>>>>> I ask that critical as some queries require to sync messages to all
>>>>>> clients of a room.
>>>>>> This can happen 1000 times in a single second if you think about
>>>>>> having up to 1000 concurrent user sessions.
>>>>>>
>>>>>> For example:
>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>>>                     .getConnections();
>>>>>> ==> iterates through all connection of the scope.
>>>>>>
>>>>>> Now the new thing is that for every connection you will create a
>>>>>> query for the RoomClient Object.
>>>>>> This is simply impossible.
>>>>>>
>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>> The RoomClient is a typical Session object and it should stay in the
>>>>>> session.
>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>> We are making a real time application, there is no chance to run
>>>>>> queries in sync methods.
>>>>>>
>>>>>> Can we find some consens here? I know you must have refactored
>>>>>> already a lot but I strictly did implement zero db related stuff in sync
>>>>>> methods.
>>>>>>
>>>>>> There might be a chance for some events to trigger db actions.However
>>>>>> I don't think having two times the RoomClient stored (one time session,
>>>>>> second time database) makes sense.
>>>>>>
>>>>>> What are you thoughts on this?
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>>
>>>>>>> Hi Maxim,
>>>>>>>
>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>
>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>
>>>>>>> We calc the current users online by iterating through the Red5
>>>>>>> Connections.
>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>
>>>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>>>> annotate it with:
>>>>>>> @org.simpleframework.xml.Transient
>>>>>>> same like roomOrganisations.
>>>>>>>
>>>>>>> Sebastian
>>>>>>>
>>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>>
>>>>>>>  Author: solomax
>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>> New Revision: 1400075
>>>>>>>>
>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>> Log:
>>>>>>>> Wicket: calendar form is improved
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>>
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>> URL:
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>                 return q.getSingleResult();
>>>>>>>>         }
>>>>>>>>
>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>> +                               "SELECT r from Rooms r LEFT JOIN
>>>>>>>> FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>>>>> r.name ASC", Rooms.class);
>>>>>>>> +               return q.getResultList();
>>>>>>>> +       }
>>>>>>>> +
>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>> c.room.currentusers "
>>>>>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted = false
>>>>>>>> "
>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>> +               return q.getResultList();
>>>>>>>> +       }
>>>>>>>> +
>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>                 /* Red5SIP integration
>>>>>>>> *******************************************************************************/
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>> URL:
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>  import javax.persistence.Table;
>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>
>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>         private String name;
>>>>>>>>
>>>>>>>>         @Lob
>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>         private String comment;
>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>>>>> ArrayList<Rooms_Organisation>();
>>>>>>>>
>>>>>>>> -       /*
>>>>>>>> -        * Non persistent attributes
>>>>>>>> -        */
>>>>>>>> -       @Transient
>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>
>>>>>>>>         public String getComment() {
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>> URL:
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>   */
>>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>
>>>>>>>> +import java.util.ArrayList;
>>>>>>>> +import java.util.List;
>>>>>>>> +
>>>>>>>> +import
>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>  import
>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>> +import
>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>> +import
>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>
>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>         private static final long serialVersionUID =
>>>>>>>> -1764738237821487526L;
>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>
>>>>>>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>>>>>>                 super(id, model);
>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>
>>>>>>>>                 add(new
>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>                 add(new TextArea<String>("appointmentDescription"));
>>>>>>>> +               add(new TextField<String>("appointmentLocation"));
>>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>> PasswordTextField("password");
>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>> +               add(pwd);
>>>>>>>> +
>>>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>>>> +                               "remind"
>>>>>>>> +                               ,
>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>> +                               , new
>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>> +
>>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>>> +                               "room.roomtype"
>>>>>>>> +                               ,
>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>> +                               , new
>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>> +               add(roomType);
>>>>>>>> +
>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>> +                               "room"
>>>>>>>> +                               , getRoomList()
>>>>>>>> +                               , new ChoiceRenderer<Rooms>("name",
>>>>>>>> "rooms_id"));
>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>> +               add(room);
>>>>>>>> +
>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>> +                       private static final long serialVersionUID
>>>>>>>> = -3743113990890386035L;
>>>>>>>> +
>>>>>>>> +                       @Override
>>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>>> target) {
>>>>>>>> +                               createRoom = getConvertedInput();
>>>>>>>> +
>>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>>> +                       }
>>>>>>>> +               });
>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>> +                       private static final long serialVersionUID
>>>>>>>> = 6041200584296439976L;
>>>>>>>> +
>>>>>>>> +                       @Override
>>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>>> target) {
>>>>>>>> +
>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>>>>> +                               target.add(pwd);
>>>>>>>> +                       }
>>>>>>>> +               });
>>>>>>>> +       }
>>>>>>>> +
>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>> +               return
>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>> +       }
>>>>>>>> +
>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>> {
>>>>>>>> +
>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>> +               }
>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>>> +               }
>>>>>>>> +               return result;
>>>>>>>>         }
>>>>>>>>  }
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>> URL:
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>                                         closeOnEscape: true
>>>>>>>>                                         , resizable: true
>>>>>>>> -                                       , width: 400
>>>>>>>> +                                       , width: 450
>>>>>>>>                                         , autoOpen: false
>>>>>>>>                                         , modal: true
>>>>>>>>                                 });
>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>                                                 <td><input
>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>                                         </tr>
>>>>>>>> -                                       <!-- tr>
>>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>>> -                                               <td>
>>>>>>>> -
>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>> -
>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>> -                                               </td>
>>>>>>>> +                                       <tr>
>>>>>>>> +
>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>> +                                               <td><span
>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>> +                                       </tr>
>>>>>>>> +                                       <tr>
>>>>>>>> +
>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>> +                                               <td><span
>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>> -                                               <td><select
>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>> +                                               <td><select
>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>>                                                 <td
>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>> -                                               <td><select
>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>> +                                               <td><select
>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>                                                 <td><select
>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>> -                                               <td
>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>> +                                               <td
>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>> -                                               <td><input
>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>> +                                               <td><input
>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <tr>
>>>>>>>>                                                 <td
>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>                                         </tr>
>>>>>>>> +                                       <!--
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>                                                 <td><select
>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>> -                                       </tr>
>>>>>>>> +                                       </tr -->
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>                                                 <td><input
>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>> -                                       </tr-->
>>>>>>>> +                                       </tr>
>>>>>>>>                                         <tr>
>>>>>>>>
>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>> -                                               <td><input
>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>> +                                               <td><textarea
>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>                                         </tr>
>>>>>>>>                                         <!-- tr>
>>>>>>>>                                                 <td colspan="2"
>>>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>>>> -                                       </tr-->
>>>>>>>> +                                       </tr -->
>>>>>>>>                                 </table>
>>>>>>>>                         </form>
>>>>>>>>                 </div>
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>> URL:
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>                                 Calendar end =
>>>>>>>> WebSession.getCalendar();
>>>>>>>>
>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>
>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>> +
>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>> +                               }
>>>>>>>>                                 Appointment a = new Appointment();
>>>>>>>>
>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>
>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Sebastian Wagner
>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>> http://www.webbase-design.de
>>>>>>> http://www.wagner-sebastian.com
>>>>>>> seba.wagner@gmail.com
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>>
>>>>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
Sorry but:
for (RoomClient rc: allClient) {
   if (rc.getPublicSID().equals(_publicSID) {
      return rc;
   }
}

That is simply not true.
There are _some_ implementations where it was needed that you need to get
the RoomClient by its public SID. However this usage was quite limited.

In general it was the way I described it:
The maps key was the streamid. And the streamid was obtained from the
IConnection of each stream.

http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
Line 118, that was the function that was mainly in use all over the
application.
There is no sorting, there is no iteration => nothing.

Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52 of
matches.
Every of this call is now replaced by a single DB query.
And if you iterate like described through all connection (like it is in
EVERY snyc method)
You will do a single query for EVERY connection.
Like 100 users in a room => 100 queries.
Think about the green dot that blinks every time you speak in the video pod:
If it gets visible => one sync message
If its get transparent => one sync message.
If you have a quite good and sensitive micro it will flush 10 mabye 10
times per second.
per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND
=> that is just impossible !!
And that is just a SINGLE videopod with 100 users watching. Now scale that
up to 1000 concurrent rooms with  4x4 meetings where every user has micro
turned on ?! Should we calc the number of database queries really?!

Sorry we will not follow that route :)

Sebastian

2012/10/22 Maxim Solodovnik <so...@gmail.com>

> Previous solution was:
>
> for (RoomClient rc: allClient) {
>    if (rc.getPublicSID().equals(_publicSID) {
>       return rc;
>    }
> }
>
> + screen sharing clients were filtered same way.
> Right now we can filter all sessions with 1 query this is why the code can
> work faster (after minor changes in iterating logic)
>
> I'm not insist RoomClient should be DB object. But having it as DB object
> was the only option to have user count in the room (in case Rooms are on
> the different servers).
>
> I believe right now org.apache.openmeetings.web.app.WebSession will be
> session object.
> I hope everything except audio and video will move to Wicket :)
>
>
> On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
> seba.wagner@gmail.com> wrote:
>
>> Hi Maxim,
>>
>> you can't persist on the argumentation that a HashMap stored in the
>> memory is slower then doing a single query for every entry of the map ?
>> Basicaly the previous implementation was a single HashMap.
>> Getting a RoomClient from this map was:
>> map.get($streamId)
>> and now this single line is replaced by a Database query. The performance
>> of this single line  is ... I guess smaller then 1 millisecond. How can you
>> say that a "Right now I think the current code should work faster or the
>> same as previous one." :)
>>
>> I guess you had some other requirements that made you implement this.
>> For example for the clustering solution.
>> However I also persist on my view:
>> A database is _not_ the right place for storing session variables. This
>> is simply a bad design decision that will cost a lot of performance in the
>> future.
>>
>> Could you explain why there is a need for having the RoomClient in the
>> database? Maybe we can resolve those requirements differently so that we
>> can have the RoomClient back in memory.
>>
>> Sebastian
>>
>>
>> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>>
>>> Sorry for double post.
>>>
>>> Correct me if I'm wrong, but i think "Transient for XML export/import"
>>> is not necessary since it doesn't have @Element annotation
>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com>
>>> wrote:
>>>
>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>> Current changes only make the calls faster (since DB is quered only
>>>> once)
>>>>
>>>> I'll try to create couple of tests. Right now I think the current code
>>>> should work faster or the same as previous one.
>>>>
>>>> Old code did lots of full filterings of RommsClient hash map to get
>>>> subset required.
>>>>
>>>> I tests will show I'm wrong on this I'll try to tune up openjpa cache
>>>> and if it doesn't help will split RoomClient to the couple of objects
>>>> and/or will create hashtable in parallel to speed up things.
>>>>
>>>> But I hope everything is not so slow since these changes are present in
>>>> 2.0 and nobody reports performance degradation.
>>>>
>>>> Sorry for typos, I'm from mobile phone
>>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>>>> wrote:
>>>>
>>>>> I guess this happened lately in trunk.
>>>>> How are we the in the future planning to determine the current users
>>>>> in the room.
>>>>> Session or database based?
>>>>>
>>>>> I ask that critical as some queries require to sync messages to all
>>>>> clients of a room.
>>>>> This can happen 1000 times in a single second if you think about
>>>>> having up to 1000 concurrent user sessions.
>>>>>
>>>>> For example:
>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>>                     .getConnections();
>>>>> ==> iterates through all connection of the scope.
>>>>>
>>>>> Now the new thing is that for every connection you will create a query
>>>>> for the RoomClient Object.
>>>>> This is simply impossible.
>>>>>
>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>> The RoomClient is a typical Session object and it should stay in the
>>>>> session.
>>>>> It is the same issue like with the WhiteboardObject.
>>>>> We are making a real time application, there is no chance to run
>>>>> queries in sync methods.
>>>>>
>>>>> Can we find some consens here? I know you must have refactored already
>>>>> a lot but I strictly did implement zero db related stuff in sync methods.
>>>>>
>>>>> There might be a chance for some events to trigger db actions.However
>>>>> I don't think having two times the RoomClient stored (one time session,
>>>>> second time database) makes sense.
>>>>>
>>>>> What are you thoughts on this?
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>>
>>>>>> Hi Maxim,
>>>>>>
>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>
>>>>>>     @JoinColumn(name = "room_id")
>>>>>>     private List<RoomClient> currentusers;
>>>>>>
>>>>>> We calc the current users online by iterating through the Red5
>>>>>> Connections.
>>>>>> In which OpenMeetings version was it changed?
>>>>>>
>>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>>> annotate it with:
>>>>>> @org.simpleframework.xml.Transient
>>>>>> same like roomOrganisations.
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/19 <so...@apache.org>
>>>>>>
>>>>>>  Author: solomax
>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>> New Revision: 1400075
>>>>>>>
>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>> Log:
>>>>>>> Wicket: calendar form is improved
>>>>>>>
>>>>>>> Modified:
>>>>>>>
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>
>>>>>>> Modified:
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>> URL:
>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>                 return q.getSingleResult();
>>>>>>>         }
>>>>>>>
>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>> +                               "SELECT r from Rooms r LEFT JOIN
>>>>>>> FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>>>> r.name ASC", Rooms.class);
>>>>>>> +               return q.getResultList();
>>>>>>> +       }
>>>>>>> +
>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>> c.room.currentusers "
>>>>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>>>>> +               + "AND c.deleted = false AND c.room.deleted = false "
>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>> +               return q.getResultList();
>>>>>>> +       }
>>>>>>> +
>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>                 /* Red5SIP integration
>>>>>>> *******************************************************************************/
>>>>>>>
>>>>>>> Modified:
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>> URL:
>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>  import javax.persistence.Table;
>>>>>>> -import javax.persistence.Transient;
>>>>>>>
>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>         private String name;
>>>>>>>
>>>>>>>         @Lob
>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>         @Column(name = "comment_field")
>>>>>>>         @Element(data = true, required = false)
>>>>>>>         private String comment;
>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>>>> ArrayList<Rooms_Organisation>();
>>>>>>>
>>>>>>> -       /*
>>>>>>> -        * Non persistent attributes
>>>>>>> -        */
>>>>>>> -       @Transient
>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>
>>>>>>>         public String getComment() {
>>>>>>>
>>>>>>> Modified:
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>> URL:
>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>   */
>>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>>
>>>>>>> +import java.util.ArrayList;
>>>>>>> +import java.util.List;
>>>>>>> +
>>>>>>> +import
>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>  import
>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>> +import
>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>> +import
>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>
>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>         private static final long serialVersionUID =
>>>>>>> -1764738237821487526L;
>>>>>>> +       private boolean createRoom = true;
>>>>>>>
>>>>>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>>>>>                 super(id, model);
>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>
>>>>>>>                 add(new
>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>                 add(new TextArea<String>("appointmentDescription"));
>>>>>>> +               add(new TextField<String>("appointmentLocation"));
>>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>> +               final PasswordTextField pwd = new
>>>>>>> PasswordTextField("password");
>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>> +               add(pwd);
>>>>>>> +
>>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>>> +                               "remind"
>>>>>>> +                               ,
>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>> +                               , new
>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>> +
>>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>>> DropDownChoice<RoomTypes>(
>>>>>>> +                               "room.roomtype"
>>>>>>> +                               ,
>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>> +                               , new
>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>> +               add(roomType);
>>>>>>> +
>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>> DropDownChoice<Rooms>(
>>>>>>> +                               "room"
>>>>>>> +                               , getRoomList()
>>>>>>> +                               , new ChoiceRenderer<Rooms>("name",
>>>>>>> "rooms_id"));
>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>> +               add(room);
>>>>>>> +
>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>> +                       private static final long serialVersionUID =
>>>>>>> -3743113990890386035L;
>>>>>>> +
>>>>>>> +                       @Override
>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>> target) {
>>>>>>> +                               createRoom = getConvertedInput();
>>>>>>> +
>>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>>> +                       }
>>>>>>> +               });
>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>> +                       private static final long serialVersionUID =
>>>>>>> 6041200584296439976L;
>>>>>>> +
>>>>>>> +                       @Override
>>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>>> target) {
>>>>>>> +
>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>>>> +                               target.add(pwd);
>>>>>>> +                       }
>>>>>>> +               });
>>>>>>> +       }
>>>>>>> +
>>>>>>> +       private boolean isPwdProtected() {
>>>>>>> +               return
>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>> +       }
>>>>>>> +
>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>> +               //FIXME need to be reviewed
>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>> +               for (Organisation_Users ou :
>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>> {
>>>>>>> +
>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>> +               }
>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>>> +               }
>>>>>>> +               return result;
>>>>>>>         }
>>>>>>>  }
>>>>>>>
>>>>>>> Modified:
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>> URL:
>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>> (original)
>>>>>>> +++
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>                                 $('#appointment').dialog({
>>>>>>>                                         closeOnEscape: true
>>>>>>>                                         , resizable: true
>>>>>>> -                                       , width: 400
>>>>>>> +                                       , width: 450
>>>>>>>                                         , autoOpen: false
>>>>>>>                                         , modal: true
>>>>>>>                                 });
>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>
>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>                                                 <td><input
>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>                                         </tr>
>>>>>>> -                                       <!-- tr>
>>>>>>> -                                               <td>&nbsp;</td>
>>>>>>> -                                               <td>
>>>>>>> -
>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>> -
>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>> -                                               </td>
>>>>>>> +                                       <tr>
>>>>>>> +
>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>> +                                               <td><span
>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>> +                                       </tr>
>>>>>>> +                                       <tr>
>>>>>>> +
>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>> +                                               <td><span
>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>> -                                               <td><select
>>>>>>> wicket:id="notification" ></select></td>
>>>>>>> +                                               <td><select
>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>>                                                 <td
>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>> -                                               <td><select
>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>> +                                               <td><select
>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>                                                 <td><select
>>>>>>> wicket:id="room" ></select></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>> -                                               <td
>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>> +                                               <td
>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>> -                                               <td><input
>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>> +                                               <td><input
>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <tr>
>>>>>>>                                                 <td
>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>                                         </tr>
>>>>>>> +                                       <!--
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>                                                 <td><select
>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>> -                                       </tr>
>>>>>>> +                                       </tr -->
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>                                                 <td><input
>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>> -                                       </tr-->
>>>>>>> +                                       </tr>
>>>>>>>                                         <tr>
>>>>>>>
>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>> -                                               <td><input
>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>> +                                               <td><textarea
>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>                                         </tr>
>>>>>>>                                         <!-- tr>
>>>>>>>                                                 <td colspan="2"
>>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>>> -                                       </tr-->
>>>>>>> +                                       </tr -->
>>>>>>>                                 </table>
>>>>>>>                         </form>
>>>>>>>                 </div>
>>>>>>>
>>>>>>> Modified:
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>> URL:
>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>                                 Calendar end =
>>>>>>> WebSession.getCalendar();
>>>>>>>
>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>
>>>>>>> +                               if (start.equals(end)) {
>>>>>>> +
>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>> +                               }
>>>>>>>                                 Appointment a = new Appointment();
>>>>>>>
>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>
>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> seba.wagner@gmail.com
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>>
>>>>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
Previous solution was:

for (RoomClient rc: allClient) {
   if (rc.getPublicSID().equals(_publicSID) {
      return rc;
   }
}

+ screen sharing clients were filtered same way.
Right now we can filter all sessions with 1 query this is why the code can
work faster (after minor changes in iterating logic)

I'm not insist RoomClient should be DB object. But having it as DB object
was the only option to have user count in the room (in case Rooms are on
the different servers).

I believe right now org.apache.openmeetings.web.app.WebSession will be
session object.
I hope everything except audio and video will move to Wicket :)

On Mon, Oct 22, 2012 at 2:33 PM, seba.wagner@gmail.com <
seba.wagner@gmail.com> wrote:

> Hi Maxim,
>
> you can't persist on the argumentation that a HashMap stored in the memory
> is slower then doing a single query for every entry of the map ?
> Basicaly the previous implementation was a single HashMap.
> Getting a RoomClient from this map was:
> map.get($streamId)
> and now this single line is replaced by a Database query. The performance
> of this single line  is ... I guess smaller then 1 millisecond. How can you
> say that a "Right now I think the current code should work faster or the
> same as previous one." :)
>
> I guess you had some other requirements that made you implement this.
> For example for the clustering solution.
> However I also persist on my view:
> A database is _not_ the right place for storing session variables. This is
> simply a bad design decision that will cost a lot of performance in the
> future.
>
> Could you explain why there is a need for having the RoomClient in the
> database? Maybe we can resolve those requirements differently so that we
> can have the RoomClient back in memory.
>
> Sebastian
>
>
> 2012/10/19 Maxim Solodovnik <so...@gmail.com>
>
>> Sorry for double post.
>>
>> Correct me if I'm wrong, but i think "Transient for XML export/import" is
>> not necessary since it doesn't have @Element annotation
>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com> wrote:
>>
>>> RoomClient was mooved to the DB while I implemented cluster.
>>> Current changes only make the calls faster (since DB is quered only once)
>>>
>>> I'll try to create couple of tests. Right now I think the current code
>>> should work faster or the same as previous one.
>>>
>>> Old code did lots of full filterings of RommsClient hash map to get
>>> subset required.
>>>
>>> I tests will show I'm wrong on this I'll try to tune up openjpa cache
>>> and if it doesn't help will split RoomClient to the couple of objects
>>> and/or will create hashtable in parallel to speed up things.
>>>
>>> But I hope everything is not so slow since these changes are present in
>>> 2.0 and nobody reports performance degradation.
>>>
>>> Sorry for typos, I'm from mobile phone
>>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>>> wrote:
>>>
>>>> I guess this happened lately in trunk.
>>>> How are we the in the future planning to determine the current users in
>>>> the room.
>>>> Session or database based?
>>>>
>>>> I ask that critical as some queries require to sync messages to all
>>>> clients of a room.
>>>> This can happen 1000 times in a single second if you think about having
>>>> up to 1000 concurrent user sessions.
>>>>
>>>> For example:
>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>>                     .getConnections();
>>>> ==> iterates through all connection of the scope.
>>>>
>>>> Now the new thing is that for every connection you will create a query
>>>> for the RoomClient Object.
>>>> This is simply impossible.
>>>>
>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>> The RoomClient is a typical Session object and it should stay in the
>>>> session.
>>>> It is the same issue like with the WhiteboardObject.
>>>> We are making a real time application, there is no chance to run
>>>> queries in sync methods.
>>>>
>>>> Can we find some consens here? I know you must have refactored already
>>>> a lot but I strictly did implement zero db related stuff in sync methods.
>>>>
>>>> There might be a chance for some events to trigger db actions.However I
>>>> don't think having two times the RoomClient stored (one time session,
>>>> second time database) makes sense.
>>>>
>>>> What are you thoughts on this?
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>>
>>>>> Hi Maxim,
>>>>>
>>>>> I don't understand this new code in the Rooms Entity:
>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>
>>>>>     @JoinColumn(name = "room_id")
>>>>>     private List<RoomClient> currentusers;
>>>>>
>>>>> We calc the current users online by iterating through the Red5
>>>>> Connections.
>>>>> In which OpenMeetings version was it changed?
>>>>>
>>>>> I guess you can set it Transient for XML export/import. So maybe
>>>>> annotate it with:
>>>>> @org.simpleframework.xml.Transient
>>>>> same like roomOrganisations.
>>>>>
>>>>> Sebastian
>>>>>
>>>>> 2012/10/19 <so...@apache.org>
>>>>>
>>>>>  Author: solomax
>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>> New Revision: 1400075
>>>>>>
>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>> Log:
>>>>>> Wicket: calendar form is improved
>>>>>>
>>>>>> Modified:
>>>>>>
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>
>>>>>> Modified:
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>> URL:
>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>> (original)
>>>>>> +++
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>> Fri Oct 19 12:39:38 2012
>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>                 return q.getSingleResult();
>>>>>>         }
>>>>>>
>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>> +               //TypedQuery<Rooms> q =
>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>> +                               "SELECT r from Rooms r LEFT JOIN
>>>>>> FETCH r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>>> r.name ASC", Rooms.class);
>>>>>> +               return q.getResultList();
>>>>>> +       }
>>>>>> +
>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>> c.room.currentusers "
>>>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>>>> +               + "AND c.deleted = false AND c.room.deleted = false "
>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>> +               q.setParameter("orgId", orgId);
>>>>>> +               return q.getResultList();
>>>>>> +       }
>>>>>> +
>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>                 /* Red5SIP integration
>>>>>> *******************************************************************************/
>>>>>>
>>>>>> Modified:
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>> URL:
>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>> (original)
>>>>>> +++
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>> Fri Oct 19 12:39:38 2012
>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>  import javax.persistence.OneToMany;
>>>>>>  import javax.persistence.OneToOne;
>>>>>>  import javax.persistence.Table;
>>>>>> -import javax.persistence.Transient;
>>>>>>
>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>         private String name;
>>>>>>
>>>>>>         @Lob
>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>         @Column(name = "comment_field")
>>>>>>         @Element(data = true, required = false)
>>>>>>         private String comment;
>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>         @org.simpleframework.xml.Transient
>>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>>> ArrayList<Rooms_Organisation>();
>>>>>>
>>>>>> -       /*
>>>>>> -        * Non persistent attributes
>>>>>> -        */
>>>>>> -       @Transient
>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>         private List<RoomClient> currentusers;
>>>>>>
>>>>>>         public String getComment() {
>>>>>>
>>>>>> Modified:
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>> URL:
>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>> (original)
>>>>>> +++
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>> Fri Oct 19 12:39:38 2012
>>>>>> @@ -18,14 +18,36 @@
>>>>>>   */
>>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>>
>>>>>> +import java.util.ArrayList;
>>>>>> +import java.util.List;
>>>>>> +
>>>>>> +import
>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>  import
>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>> +import
>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>> +import
>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>  import org.apache.wicket.model.IModel;
>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>
>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>         private static final long serialVersionUID =
>>>>>> -1764738237821487526L;
>>>>>> +       private boolean createRoom = true;
>>>>>>
>>>>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>>>>                 super(id, model);
>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>
>>>>>>                 add(new RequiredTextField<String>("appointmentName"));
>>>>>>                 add(new TextArea<String>("appointmentDescription"));
>>>>>> +               add(new TextField<String>("appointmentLocation"));
>>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>> +               final PasswordTextField pwd = new
>>>>>> PasswordTextField("password");
>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>> +               add(pwd);
>>>>>> +
>>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>>> +                               "remind"
>>>>>> +                               ,
>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>> +                               , new
>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>> +
>>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>>> DropDownChoice<RoomTypes>(
>>>>>> +                               "room.roomtype"
>>>>>> +                               ,
>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>> +                               , new
>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>> +               roomType.setEnabled(createRoom);
>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>> +               add(roomType);
>>>>>> +
>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>> DropDownChoice<Rooms>(
>>>>>> +                               "room"
>>>>>> +                               , getRoomList()
>>>>>> +                               , new ChoiceRenderer<Rooms>("name",
>>>>>> "rooms_id"));
>>>>>> +               room.setEnabled(!createRoom);
>>>>>> +               room.setOutputMarkupId(true);
>>>>>> +               add(room);
>>>>>> +
>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>> +                       private static final long serialVersionUID =
>>>>>> -3743113990890386035L;
>>>>>> +
>>>>>> +                       @Override
>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>> target) {
>>>>>> +                               createRoom = getConvertedInput();
>>>>>> +
>>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>>> +                       }
>>>>>> +               });
>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>> +                       private static final long serialVersionUID =
>>>>>> 6041200584296439976L;
>>>>>> +
>>>>>> +                       @Override
>>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>>> target) {
>>>>>> +
>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>>> +                               target.add(pwd);
>>>>>> +                       }
>>>>>> +               });
>>>>>> +       }
>>>>>> +
>>>>>> +       private boolean isPwdProtected() {
>>>>>> +               return
>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>> +       }
>>>>>> +
>>>>>> +       private List<Rooms> getRoomList() {
>>>>>> +               //FIXME need to be reviewed
>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>> +               for (Organisation_Users ou :
>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>> {
>>>>>> +
>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>> +               }
>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>> +                       result.add(getModelObject().getRoom());
>>>>>> +               }
>>>>>> +               return result;
>>>>>>         }
>>>>>>  }
>>>>>>
>>>>>> Modified:
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>> URL:
>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>> (original)
>>>>>> +++
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>> Fri Oct 19 12:39:38 2012
>>>>>> @@ -71,7 +71,7 @@
>>>>>>                                 $('#appointment').dialog({
>>>>>>                                         closeOnEscape: true
>>>>>>                                         , resizable: true
>>>>>> -                                       , width: 400
>>>>>> +                                       , width: 450
>>>>>>                                         , autoOpen: false
>>>>>>                                         , modal: true
>>>>>>                                 });
>>>>>> @@ -89,53 +89,55 @@
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="572" /></td>
>>>>>>                                                 <td><input
>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>                                         </tr>
>>>>>> -                                       <!-- tr>
>>>>>> -                                               <td>&nbsp;</td>
>>>>>> -                                               <td>
>>>>>> -
>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>> wicket:id="appointmentStarttime" />
>>>>>> -
>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>> wicket:id="appointmentEndtime" />
>>>>>> -                                               </td>
>>>>>> +                                       <tr>
>>>>>> +                                               <td><wicket:ommessage
>>>>>> key="570" /></td>
>>>>>> +                                               <td><span
>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>> +                                       </tr>
>>>>>> +                                       <tr>
>>>>>> +                                               <td><wicket:ommessage
>>>>>> key="571" /></td>
>>>>>> +                                               <td><span
>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="565" /></td>
>>>>>> -                                               <td><select
>>>>>> wicket:id="notification" ></select></td>
>>>>>> +                                               <td><select
>>>>>> wicket:id="remind" ></select></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td
>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="619" /></td>
>>>>>> -                                               <td><select
>>>>>> wicket:id="roomType" ></select></td>
>>>>>> +                                               <td><select
>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="406" /></td>
>>>>>>                                                 <td><select
>>>>>> wicket:id="room" ></select></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>> -                                               <td
>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>> +                                               <td
>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected"
>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="525" /></td>
>>>>>> -                                               <td><input
>>>>>> type="text" wicket:id="password" /></td>
>>>>>> +                                               <td><input
>>>>>> type="password" wicket:id="password" /></td>
>>>>>>                                         </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td
>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>                                         </tr>
>>>>>> +                                       <!--
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="803" /></td>
>>>>>>                                                 <td><select
>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>> -                                       </tr>
>>>>>> +                                       </tr -->
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="569" /></td>
>>>>>>                                                 <td><input
>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>> -                                       </tr-->
>>>>>> +                                       </tr>
>>>>>>                                         <tr>
>>>>>>                                                 <td><wicket:ommessage
>>>>>> key="573" /></td>
>>>>>> -                                               <td><input
>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>> +                                               <td><textarea
>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>                                         </tr>
>>>>>>                                         <!-- tr>
>>>>>>                                                 <td colspan="2"
>>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>>> type="button" wicket:id="cancel" /></td>
>>>>>> -                                       </tr-->
>>>>>> +                                       </tr -->
>>>>>>                                 </table>
>>>>>>                         </form>
>>>>>>                 </div>
>>>>>>
>>>>>> Modified:
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>> URL:
>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>> (original)
>>>>>> +++
>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>> Fri Oct 19 12:39:38 2012
>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>                                 Calendar end =
>>>>>> WebSession.getCalendar();
>>>>>>
>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>
>>>>>> +                               if (start.equals(end)) {
>>>>>> +                                       end.add(Calendar.HOUR_OF_DAY,
>>>>>> 1);
>>>>>> +                               }
>>>>>>                                 Appointment a = new Appointment();
>>>>>>
>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>
>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sebastian Wagner
>>>>> https://twitter.com/#!/dead_lock
>>>>> http://www.webbase-design.de
>>>>> http://www.wagner-sebastian.com
>>>>> seba.wagner@gmail.com
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>>
>>>>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
Hi Maxim,

you can't persist on the argumentation that a HashMap stored in the memory
is slower then doing a single query for every entry of the map ?
Basicaly the previous implementation was a single HashMap.
Getting a RoomClient from this map was:
map.get($streamId)
and now this single line is replaced by a Database query. The performance
of this single line  is ... I guess smaller then 1 millisecond. How can you
say that a "Right now I think the current code should work faster or the
same as previous one." :)

I guess you had some other requirements that made you implement this.
For example for the clustering solution.
However I also persist on my view:
A database is _not_ the right place for storing session variables. This is
simply a bad design decision that will cost a lot of performance in the
future.

Could you explain why there is a need for having the RoomClient in the
database? Maybe we can resolve those requirements differently so that we
can have the RoomClient back in memory.

Sebastian

2012/10/19 Maxim Solodovnik <so...@gmail.com>

> Sorry for double post.
>
> Correct me if I'm wrong, but i think "Transient for XML export/import" is
> not necessary since it doesn't have @Element annotation
> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com> wrote:
>
>> RoomClient was mooved to the DB while I implemented cluster.
>> Current changes only make the calls faster (since DB is quered only once)
>>
>> I'll try to create couple of tests. Right now I think the current code
>> should work faster or the same as previous one.
>>
>> Old code did lots of full filterings of RommsClient hash map to get
>> subset required.
>>
>> I tests will show I'm wrong on this I'll try to tune up openjpa cache and
>> if it doesn't help will split RoomClient to the couple of objects and/or
>> will create hashtable in parallel to speed up things.
>>
>> But I hope everything is not so slow since these changes are present in
>> 2.0 and nobody reports performance degradation.
>>
>> Sorry for typos, I'm from mobile phone
>> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <se...@gmail.com>
>> wrote:
>>
>>> I guess this happened lately in trunk.
>>> How are we the in the future planning to determine the current users in
>>> the room.
>>> Session or database based?
>>>
>>> I ask that critical as some queries require to sync messages to all
>>> clients of a room.
>>> This can happen 1000 times in a single second if you think about having
>>> up to 1000 concurrent user sessions.
>>>
>>> For example:
>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>>                     .getConnections();
>>> ==> iterates through all connection of the scope.
>>>
>>> Now the new thing is that for every connection you will create a query
>>> for the RoomClient Object.
>>> This is simply impossible.
>>>
>>> We want to scale up to 1000 concurrent user sessions and more.
>>> The RoomClient is a typical Session object and it should stay in the
>>> session.
>>> It is the same issue like with the WhiteboardObject.
>>> We are making a real time application, there is no chance to run queries
>>> in sync methods.
>>>
>>> Can we find some consens here? I know you must have refactored already a
>>> lot but I strictly did implement zero db related stuff in sync methods.
>>>
>>> There might be a chance for some events to trigger db actions.However I
>>> don't think having two times the RoomClient stored (one time session,
>>> second time database) makes sense.
>>>
>>> What are you thoughts on this?
>>>
>>> Sebastian
>>>
>>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>>
>>>> Hi Maxim,
>>>>
>>>> I don't understand this new code in the Rooms Entity:
>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>
>>>>     @JoinColumn(name = "room_id")
>>>>     private List<RoomClient> currentusers;
>>>>
>>>> We calc the current users online by iterating through the Red5
>>>> Connections.
>>>> In which OpenMeetings version was it changed?
>>>>
>>>> I guess you can set it Transient for XML export/import. So maybe
>>>> annotate it with:
>>>> @org.simpleframework.xml.Transient
>>>> same like roomOrganisations.
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/19 <so...@apache.org>
>>>>
>>>>  Author: solomax
>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>> New Revision: 1400075
>>>>>
>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>> Log:
>>>>> Wicket: calendar form is improved
>>>>>
>>>>> Modified:
>>>>>
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>
>>>>> Modified:
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> ---
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>> (original)
>>>>> +++
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>> Fri Oct 19 12:39:38 2012
>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>                 return q.getSingleResult();
>>>>>         }
>>>>>
>>>>> +       public List<Rooms> getPublicRooms() {
>>>>> +               //TypedQuery<Rooms> q =
>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>> +                               "SELECT r from Rooms r LEFT JOIN FETCH
>>>>> r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>>> r.name ASC", Rooms.class);
>>>>> +               return q.getResultList();
>>>>> +       }
>>>>> +
>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>> c.room.currentusers "
>>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>>> +               + "AND c.deleted = false AND c.room.deleted = false "
>>>>> +               + "AND c.organisation.deleted = false "
>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>> +               q.setParameter("orgId", orgId);
>>>>> +               return q.getResultList();
>>>>> +       }
>>>>> +
>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>                 if (entity.getRooms_id() == null) {
>>>>>                 /* Red5SIP integration
>>>>> *******************************************************************************/
>>>>>
>>>>> Modified:
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> ---
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>> (original)
>>>>> +++
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>> Fri Oct 19 12:39:38 2012
>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>  import javax.persistence.OneToMany;
>>>>>  import javax.persistence.OneToOne;
>>>>>  import javax.persistence.Table;
>>>>> -import javax.persistence.Transient;
>>>>>
>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>         private String name;
>>>>>
>>>>>         @Lob
>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>         @Column(name = "comment_field")
>>>>>         @Element(data = true, required = false)
>>>>>         private String comment;
>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>         @org.simpleframework.xml.Transient
>>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>>> ArrayList<Rooms_Organisation>();
>>>>>
>>>>> -       /*
>>>>> -        * Non persistent attributes
>>>>> -        */
>>>>> -       @Transient
>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>> +       @JoinColumn(name = "room_id")
>>>>>         private List<RoomClient> currentusers;
>>>>>
>>>>>         public String getComment() {
>>>>>
>>>>> Modified:
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> ---
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>> (original)
>>>>> +++
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>> Fri Oct 19 12:39:38 2012
>>>>> @@ -18,14 +18,36 @@
>>>>>   */
>>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>>
>>>>> +import java.util.ArrayList;
>>>>> +import java.util.List;
>>>>> +
>>>>> +import
>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>  import org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>> +import
>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>> +import
>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>  import org.apache.wicket.model.IModel;
>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>
>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>         private static final long serialVersionUID =
>>>>> -1764738237821487526L;
>>>>> +       private boolean createRoom = true;
>>>>>
>>>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>>>                 super(id, model);
>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>
>>>>>                 add(new RequiredTextField<String>("appointmentName"));
>>>>>                 add(new TextArea<String>("appointmentDescription"));
>>>>> +               add(new TextField<String>("appointmentLocation"));
>>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>> +               final PasswordTextField pwd = new
>>>>> PasswordTextField("password");
>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>> +               pwd.setOutputMarkupId(true);
>>>>> +               add(pwd);
>>>>> +
>>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>>> +                               "remind"
>>>>> +                               ,
>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>> +                               , new
>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>> +
>>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>>> DropDownChoice<RoomTypes>(
>>>>> +                               "room.roomtype"
>>>>> +                               ,
>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>> +                               , new
>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>> +               roomType.setEnabled(createRoom);
>>>>> +               roomType.setOutputMarkupId(true);
>>>>> +               add(roomType);
>>>>> +
>>>>> +               final DropDownChoice<Rooms> room = new
>>>>> DropDownChoice<Rooms>(
>>>>> +                               "room"
>>>>> +                               , getRoomList()
>>>>> +                               , new ChoiceRenderer<Rooms>("name",
>>>>> "rooms_id"));
>>>>> +               room.setEnabled(!createRoom);
>>>>> +               room.setOutputMarkupId(true);
>>>>> +               add(room);
>>>>> +
>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>> +                       private static final long serialVersionUID =
>>>>> -3743113990890386035L;
>>>>> +
>>>>> +                       @Override
>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>> target) {
>>>>> +                               createRoom = getConvertedInput();
>>>>> +
>>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>>> +                       }
>>>>> +               });
>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>> +                       private static final long serialVersionUID =
>>>>> 6041200584296439976L;
>>>>> +
>>>>> +                       @Override
>>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>>> target) {
>>>>> +
>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>> +                               pwd.setEnabled(isPwdProtected());
>>>>> +                               target.add(pwd);
>>>>> +                       }
>>>>> +               });
>>>>> +       }
>>>>> +
>>>>> +       private boolean isPwdProtected() {
>>>>> +               return
>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>> +       }
>>>>> +
>>>>> +       private List<Rooms> getRoomList() {
>>>>> +               //FIXME need to be reviewed
>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>>> +               result.addAll(dao.getPublicRooms());
>>>>> +               for (Organisation_Users ou :
>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>> {
>>>>> +
>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>> +               }
>>>>> +               if (getModelObject().getRoom() != null &&
>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>> +                       result.add(getModelObject().getRoom());
>>>>> +               }
>>>>> +               return result;
>>>>>         }
>>>>>  }
>>>>>
>>>>> Modified:
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> ---
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>> (original)
>>>>> +++
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>> Fri Oct 19 12:39:38 2012
>>>>> @@ -71,7 +71,7 @@
>>>>>                                 $('#appointment').dialog({
>>>>>                                         closeOnEscape: true
>>>>>                                         , resizable: true
>>>>> -                                       , width: 400
>>>>> +                                       , width: 450
>>>>>                                         , autoOpen: false
>>>>>                                         , modal: true
>>>>>                                 });
>>>>> @@ -89,53 +89,55 @@
>>>>>                                                 <td><wicket:ommessage
>>>>> key="572" /></td>
>>>>>                                                 <td><input type="text"
>>>>> wicket:id="appointmentName" /></td>
>>>>>                                         </tr>
>>>>> -                                       <!-- tr>
>>>>> -                                               <td>&nbsp;</td>
>>>>> -                                               <td>
>>>>> -
>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>> wicket:id="appointmentStarttime" />
>>>>> -
>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>> wicket:id="appointmentEndtime" />
>>>>> -                                               </td>
>>>>> +                                       <tr>
>>>>> +                                               <td><wicket:ommessage
>>>>> key="570" /></td>
>>>>> +                                               <td><span
>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>> +                                       </tr>
>>>>> +                                       <tr>
>>>>> +                                               <td><wicket:ommessage
>>>>> key="571" /></td>
>>>>> +                                               <td><span
>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="565" /></td>
>>>>> -                                               <td><select
>>>>> wicket:id="notification" ></select></td>
>>>>> +                                               <td><select
>>>>> wicket:id="remind" ></select></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>>                                                 <td colspan="2"><input
>>>>> type="checkbox" wicket:id="createRoom" /><wicket:ommessage key="1509"
>>>>> /></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="619" /></td>
>>>>> -                                               <td><select
>>>>> wicket:id="roomType" ></select></td>
>>>>> +                                               <td><select
>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="406" /></td>
>>>>>                                                 <td><select
>>>>> wicket:id="room" ></select></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>> -                                               <td colspan="2"><input
>>>>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>>>>> key="1509" /></td>
>>>>> +                                               <td colspan="2"><input
>>>>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>>>>> key="524" /></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="525" /></td>
>>>>> -                                               <td><input type="text"
>>>>> wicket:id="password" /></td>
>>>>> +                                               <td><input
>>>>> type="password" wicket:id="password" /></td>
>>>>>                                         </tr>
>>>>>                                         <tr>
>>>>>                                                 <td
>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>                                         </tr>
>>>>> +                                       <!--
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="803" /></td>
>>>>>                                                 <td><select
>>>>> wicket:id="meetingMember" ></select></td>
>>>>> -                                       </tr>
>>>>> +                                       </tr -->
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="569" /></td>
>>>>>                                                 <td><input type="text"
>>>>> wicket:id="appointmentLocation" /></td>
>>>>> -                                       </tr-->
>>>>> +                                       </tr>
>>>>>                                         <tr>
>>>>>                                                 <td><wicket:ommessage
>>>>> key="573" /></td>
>>>>> -                                               <td><input type="text"
>>>>> wicket:id="appointmentDescription" /></td>
>>>>> +                                               <td><textarea
>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>                                         </tr>
>>>>>                                         <!-- tr>
>>>>>                                                 <td colspan="2"
>>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>>> type="button" wicket:id="cancel" /></td>
>>>>> -                                       </tr-->
>>>>> +                                       </tr -->
>>>>>                                 </table>
>>>>>                         </form>
>>>>>                 </div>
>>>>>
>>>>> Modified:
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> ---
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>> (original)
>>>>> +++
>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>> Fri Oct 19 12:39:38 2012
>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>                                 Calendar end =
>>>>> WebSession.getCalendar();
>>>>>
>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>
>>>>> +                               if (start.equals(end)) {
>>>>> +                                       end.add(Calendar.HOUR_OF_DAY,
>>>>> 1);
>>>>> +                               }
>>>>>                                 Appointment a = new Appointment();
>>>>>
>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>                                 a.setAppointmentEndtime(end.getTime());
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> seba.wagner@gmail.com
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>>
>>>


-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
Sorry for double post.

Correct me if I'm wrong, but i think "Transient for XML export/import" is
not necessary since it doesn't have @Element annotation
On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <so...@gmail.com> wrote:

> RoomClient was mooved to the DB while I implemented cluster.
> Current changes only make the calls faster (since DB is quered only once)
>
> I'll try to create couple of tests. Right now I think the current code
> should work faster or the same as previous one.
>
> Old code did lots of full filterings of RommsClient hash map to get subset
> required.
>
> I tests will show I'm wrong on this I'll try to tune up openjpa cache and
> if it doesn't help will split RoomClient to the couple of objects and/or
> will create hashtable in parallel to speed up things.
>
> But I hope everything is not so slow since these changes are present in
> 2.0 and nobody reports performance degradation.
>
> Sorry for typos, I'm from mobile phone
> On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <se...@gmail.com>
> wrote:
>
>> I guess this happened lately in trunk.
>> How are we the in the future planning to determine the current users in
>> the room.
>> Session or database based?
>>
>> I ask that critical as some queries require to sync messages to all
>> clients of a room.
>> This can happen 1000 times in a single second if you think about having
>> up to 1000 concurrent user sessions.
>>
>> For example:
>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
>> => Collection<Set<IConnection>> conCollection = current.getScope()
>>                     .getConnections();
>> ==> iterates through all connection of the scope.
>>
>> Now the new thing is that for every connection you will create a query
>> for the RoomClient Object.
>> This is simply impossible.
>>
>> We want to scale up to 1000 concurrent user sessions and more.
>> The RoomClient is a typical Session object and it should stay in the
>> session.
>> It is the same issue like with the WhiteboardObject.
>> We are making a real time application, there is no chance to run queries
>> in sync methods.
>>
>> Can we find some consens here? I know you must have refactored already a
>> lot but I strictly did implement zero db related stuff in sync methods.
>>
>> There might be a chance for some events to trigger db actions.However I
>> don't think having two times the RoomClient stored (one time session,
>> second time database) makes sense.
>>
>> What are you thoughts on this?
>>
>> Sebastian
>>
>> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>>
>>> Hi Maxim,
>>>
>>> I don't understand this new code in the Rooms Entity:
>>>     @OneToMany(fetch = FetchType.LAZY)
>>>
>>>     @JoinColumn(name = "room_id")
>>>     private List<RoomClient> currentusers;
>>>
>>> We calc the current users online by iterating through the Red5
>>> Connections.
>>> In which OpenMeetings version was it changed?
>>>
>>> I guess you can set it Transient for XML export/import. So maybe
>>> annotate it with:
>>> @org.simpleframework.xml.Transient
>>> same like roomOrganisations.
>>>
>>> Sebastian
>>>
>>> 2012/10/19 <so...@apache.org>
>>>
>>>  Author: solomax
>>>> Date: Fri Oct 19 12:39:38 2012
>>>> New Revision: 1400075
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>> Log:
>>>> Wicket: calendar form is improved
>>>>
>>>> Modified:
>>>>
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>
>>>> Modified:
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>> (original)
>>>> +++
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>> Fri Oct 19 12:39:38 2012
>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>                 return q.getSingleResult();
>>>>         }
>>>>
>>>> +       public List<Rooms> getPublicRooms() {
>>>> +               //TypedQuery<Rooms> q =
>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>> +                               "SELECT r from Rooms r LEFT JOIN FETCH
>>>> r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>>> r.name ASC", Rooms.class);
>>>> +               return q.getResultList();
>>>> +       }
>>>> +
>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>> +                               "SELECT DISTINCT c.room FROM
>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>> c.room.currentusers "
>>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>>> +               + "AND c.deleted = false AND c.room.deleted = false "
>>>> +               + "AND c.organisation.deleted = false "
>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>> +               q.setParameter("orgId", orgId);
>>>> +               return q.getResultList();
>>>> +       }
>>>> +
>>>>         public Rooms update(Rooms entity, long userId) {
>>>>                 if (entity.getRooms_id() == null) {
>>>>                 /* Red5SIP integration
>>>> *******************************************************************************/
>>>>
>>>> Modified:
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>> (original)
>>>> +++
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>> Fri Oct 19 12:39:38 2012
>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>  import javax.persistence.OneToMany;
>>>>  import javax.persistence.OneToOne;
>>>>  import javax.persistence.Table;
>>>> -import javax.persistence.Transient;
>>>>
>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>         private String name;
>>>>
>>>>         @Lob
>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>         @Column(name = "comment_field")
>>>>         @Element(data = true, required = false)
>>>>         private String comment;
>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>         @org.simpleframework.xml.Transient
>>>>         private List<Rooms_Organisation> roomOrganisations = new
>>>> ArrayList<Rooms_Organisation>();
>>>>
>>>> -       /*
>>>> -        * Non persistent attributes
>>>> -        */
>>>> -       @Transient
>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>> +       @JoinColumn(name = "room_id")
>>>>         private List<RoomClient> currentusers;
>>>>
>>>>         public String getComment() {
>>>>
>>>> Modified:
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>> (original)
>>>> +++
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>> Fri Oct 19 12:39:38 2012
>>>> @@ -18,14 +18,36 @@
>>>>   */
>>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>>
>>>> +import java.util.ArrayList;
>>>> +import java.util.List;
>>>> +
>>>> +import
>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>  import org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>> +import
>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>> +import
>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>> +import org.apache.openmeetings.web.app.Application;
>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>  import org.apache.wicket.markup.html.form.Form;
>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>  import org.apache.wicket.model.IModel;
>>>> +import org.apache.wicket.model.PropertyModel;
>>>>
>>>>  public class CalendarForm extends Form<Appointment> {
>>>>         private static final long serialVersionUID =
>>>> -1764738237821487526L;
>>>> +       private boolean createRoom = true;
>>>>
>>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>>                 super(id, model);
>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>
>>>>                 add(new RequiredTextField<String>("appointmentName"));
>>>>                 add(new TextArea<String>("appointmentDescription"));
>>>> +               add(new TextField<String>("appointmentLocation"));
>>>> +               add(new DateTimeField("appointmentStarttime"));
>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>> +               final PasswordTextField pwd = new
>>>> PasswordTextField("password");
>>>> +               pwd.setEnabled(isPwdProtected());
>>>> +               pwd.setOutputMarkupId(true);
>>>> +               add(pwd);
>>>> +
>>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>>> +                               "remind"
>>>> +                               ,
>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>> +                               , new
>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>> +
>>>> +               final DropDownChoice<RoomTypes> roomType = new
>>>> DropDownChoice<RoomTypes>(
>>>> +                               "room.roomtype"
>>>> +                               ,
>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>> +                               , new ChoiceRenderer<RoomTypes>("name",
>>>> "roomtypes_id"));
>>>> +               roomType.setEnabled(createRoom);
>>>> +               roomType.setOutputMarkupId(true);
>>>> +               add(roomType);
>>>> +
>>>> +               final DropDownChoice<Rooms> room = new
>>>> DropDownChoice<Rooms>(
>>>> +                               "room"
>>>> +                               , getRoomList()
>>>> +                               , new ChoiceRenderer<Rooms>("name",
>>>> "rooms_id"));
>>>> +               room.setEnabled(!createRoom);
>>>> +               room.setOutputMarkupId(true);
>>>> +               add(room);
>>>> +
>>>> +               add(new AjaxCheckBox("createRoom", new
>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>> +                       private static final long serialVersionUID =
>>>> -3743113990890386035L;
>>>> +
>>>> +                       @Override
>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>> target) {
>>>> +                               createRoom = getConvertedInput();
>>>> +
>>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>>> +                       }
>>>> +               });
>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>> +                       private static final long serialVersionUID =
>>>> 6041200584296439976L;
>>>> +
>>>> +                       @Override
>>>> +                       protected void onUpdate(AjaxRequestTarget
>>>> target) {
>>>> +
>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>> +                               pwd.setEnabled(isPwdProtected());
>>>> +                               target.add(pwd);
>>>> +                       }
>>>> +               });
>>>> +       }
>>>> +
>>>> +       private boolean isPwdProtected() {
>>>> +               return
>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>> +       }
>>>> +
>>>> +       private List<Rooms> getRoomList() {
>>>> +               //FIXME need to be reviewed
>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>>> +               result.addAll(dao.getPublicRooms());
>>>> +               for (Organisation_Users ou :
>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>> {
>>>> +
>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>> +               }
>>>> +               if (getModelObject().getRoom() != null &&
>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>> +                       result.add(getModelObject().getRoom());
>>>> +               }
>>>> +               return result;
>>>>         }
>>>>  }
>>>>
>>>> Modified:
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>> (original)
>>>> +++
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>> Fri Oct 19 12:39:38 2012
>>>> @@ -71,7 +71,7 @@
>>>>                                 $('#appointment').dialog({
>>>>                                         closeOnEscape: true
>>>>                                         , resizable: true
>>>> -                                       , width: 400
>>>> +                                       , width: 450
>>>>                                         , autoOpen: false
>>>>                                         , modal: true
>>>>                                 });
>>>> @@ -89,53 +89,55 @@
>>>>                                                 <td><wicket:ommessage
>>>> key="572" /></td>
>>>>                                                 <td><input type="text"
>>>> wicket:id="appointmentName" /></td>
>>>>                                         </tr>
>>>> -                                       <!-- tr>
>>>> -                                               <td>&nbsp;</td>
>>>> -                                               <td>
>>>> -
>>>> <wicket:ommessage key="570" /><input type="text"
>>>> wicket:id="appointmentStarttime" />
>>>> -
>>>> <wicket:ommessage key="571" /><input type="text"
>>>> wicket:id="appointmentEndtime" />
>>>> -                                               </td>
>>>> +                                       <tr>
>>>> +                                               <td><wicket:ommessage
>>>> key="570" /></td>
>>>> +                                               <td><span
>>>> wicket:id="appointmentStarttime"></span></td>
>>>> +                                       </tr>
>>>> +                                       <tr>
>>>> +                                               <td><wicket:ommessage
>>>> key="571" /></td>
>>>> +                                               <td><span
>>>> wicket:id="appointmentEndtime"></span></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="565" /></td>
>>>> -                                               <td><select
>>>> wicket:id="notification" ></select></td>
>>>> +                                               <td><select
>>>> wicket:id="remind" ></select></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>>                                                 <td colspan="2"><input
>>>> type="checkbox" wicket:id="createRoom" /><wicket:ommessage key="1509"
>>>> /></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="619" /></td>
>>>> -                                               <td><select
>>>> wicket:id="roomType" ></select></td>
>>>> +                                               <td><select
>>>> wicket:id="room.roomtype" ></select></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="406" /></td>
>>>>                                                 <td><select
>>>> wicket:id="room" ></select></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>> -                                               <td colspan="2"><input
>>>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>>>> key="1509" /></td>
>>>> +                                               <td colspan="2"><input
>>>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>>>> key="524" /></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="525" /></td>
>>>> -                                               <td><input type="text"
>>>> wicket:id="password" /></td>
>>>> +                                               <td><input
>>>> type="password" wicket:id="password" /></td>
>>>>                                         </tr>
>>>>                                         <tr>
>>>>                                                 <td
>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>                                         </tr>
>>>> +                                       <!--
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="803" /></td>
>>>>                                                 <td><select
>>>> wicket:id="meetingMember" ></select></td>
>>>> -                                       </tr>
>>>> +                                       </tr -->
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="569" /></td>
>>>>                                                 <td><input type="text"
>>>> wicket:id="appointmentLocation" /></td>
>>>> -                                       </tr-->
>>>> +                                       </tr>
>>>>                                         <tr>
>>>>                                                 <td><wicket:ommessage
>>>> key="573" /></td>
>>>> -                                               <td><input type="text"
>>>> wicket:id="appointmentDescription" /></td>
>>>> +                                               <td><textarea
>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>                                         </tr>
>>>>                                         <!-- tr>
>>>>                                                 <td colspan="2"
>>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>>> type="button" wicket:id="cancel" /></td>
>>>> -                                       </tr-->
>>>> +                                       </tr -->
>>>>                                 </table>
>>>>                         </form>
>>>>                 </div>
>>>>
>>>> Modified:
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>> (original)
>>>> +++
>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>> Fri Oct 19 12:39:38 2012
>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>                                 Calendar end = WebSession.getCalendar();
>>>>
>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>
>>>> +                               if (start.equals(end)) {
>>>> +                                       end.add(Calendar.HOUR_OF_DAY,
>>>> 1);
>>>> +                               }
>>>>                                 Appointment a = new Appointment();
>>>>
>>>> a.setAppointmentStarttime(start.getTime());
>>>>                                 a.setAppointmentEndtime(end.getTime());
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> seba.wagner@gmail.com
>>>
>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>>
>>

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by Maxim Solodovnik <so...@gmail.com>.
RoomClient was mooved to the DB while I implemented cluster.
Current changes only make the calls faster (since DB is quered only once)

I'll try to create couple of tests. Right now I think the current code
should work faster or the same as previous one.

Old code did lots of full filterings of RommsClient hash map to get subset
required.

I tests will show I'm wrong on this I'll try to tune up openjpa cache and
if it doesn't help will split RoomClient to the couple of objects and/or
will create hashtable in parallel to speed up things.

But I hope everything is not so slow since these changes are present in 2.0
and nobody reports performance degradation.

Sorry for typos, I'm from mobile phone
On Oct 19, 2012 9:11 PM, "seba.wagner@gmail.com" <se...@gmail.com>
wrote:

> I guess this happened lately in trunk.
> How are we the in the future planning to determine the current users in
> the room.
> Session or database based?
>
> I ask that critical as some queries require to sync messages to all
> clients of a room.
> This can happen 1000 times in a single second if you think about having up
> to 1000 concurrent user sessions.
>
> For example:
> ScopeApplicationAdapter::syncMessageToCurrentScope(String
> remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen)
> => Collection<Set<IConnection>> conCollection = current.getScope()
>                     .getConnections();
> ==> iterates through all connection of the scope.
>
> Now the new thing is that for every connection you will create a query for
> the RoomClient Object.
> This is simply impossible.
>
> We want to scale up to 1000 concurrent user sessions and more.
> The RoomClient is a typical Session object and it should stay in the
> session.
> It is the same issue like with the WhiteboardObject.
> We are making a real time application, there is no chance to run queries
> in sync methods.
>
> Can we find some consens here? I know you must have refactored already a
> lot but I strictly did implement zero db related stuff in sync methods.
>
> There might be a chance for some events to trigger db actions.However I
> don't think having two times the RoomClient stored (one time session,
> second time database) makes sense.
>
> What are you thoughts on this?
>
> Sebastian
>
> 2012/10/19 seba.wagner@gmail.com <se...@gmail.com>
>
>> Hi Maxim,
>>
>> I don't understand this new code in the Rooms Entity:
>>     @OneToMany(fetch = FetchType.LAZY)
>>
>>     @JoinColumn(name = "room_id")
>>     private List<RoomClient> currentusers;
>>
>> We calc the current users online by iterating through the Red5
>> Connections.
>> In which OpenMeetings version was it changed?
>>
>> I guess you can set it Transient for XML export/import. So maybe annotate
>> it with:
>> @org.simpleframework.xml.Transient
>> same like roomOrganisations.
>>
>> Sebastian
>>
>> 2012/10/19 <so...@apache.org>
>>
>>  Author: solomax
>>> Date: Fri Oct 19 12:39:38 2012
>>> New Revision: 1400075
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>> Log:
>>> Wicket: calendar form is improved
>>>
>>> Modified:
>>>
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>
>>> Modified:
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>> (original)
>>> +++
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>> Fri Oct 19 12:39:38 2012
>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>                 return q.getSingleResult();
>>>         }
>>>
>>> +       public List<Rooms> getPublicRooms() {
>>> +               //TypedQuery<Rooms> q =
>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>> +               TypedQuery<Rooms> q = em.createQuery(
>>> +                               "SELECT r from Rooms r LEFT JOIN FETCH
>>> r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>>> r.name ASC", Rooms.class);
>>> +               return q.getResultList();
>>> +       }
>>> +
>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>> +               TypedQuery<Rooms> q = em.createQuery(
>>> +                               "SELECT DISTINCT c.room FROM
>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>> c.room.currentusers "
>>> +               + "WHERE c.organisation.organisation_id = :orgId "
>>> +               + "AND c.deleted = false AND c.room.deleted = false "
>>> +               + "AND c.organisation.deleted = false "
>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>> +               q.setParameter("orgId", orgId);
>>> +               return q.getResultList();
>>> +       }
>>> +
>>>         public Rooms update(Rooms entity, long userId) {
>>>                 if (entity.getRooms_id() == null) {
>>>                 /* Red5SIP integration
>>> *******************************************************************************/
>>>
>>> Modified:
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>> (original)
>>> +++
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>> Fri Oct 19 12:39:38 2012
>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>  import javax.persistence.OneToMany;
>>>  import javax.persistence.OneToOne;
>>>  import javax.persistence.Table;
>>> -import javax.persistence.Transient;
>>>
>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>         private String name;
>>>
>>>         @Lob
>>> -       // @Basic(fetch=FetchType.LAZY)
>>>         @Column(name = "comment_field")
>>>         @Element(data = true, required = false)
>>>         private String comment;
>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>         @org.simpleframework.xml.Transient
>>>         private List<Rooms_Organisation> roomOrganisations = new
>>> ArrayList<Rooms_Organisation>();
>>>
>>> -       /*
>>> -        * Non persistent attributes
>>> -        */
>>> -       @Transient
>>> +       @OneToMany(fetch = FetchType.LAZY)
>>> +       @JoinColumn(name = "room_id")
>>>         private List<RoomClient> currentusers;
>>>
>>>         public String getComment() {
>>>
>>> Modified:
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>> (original)
>>> +++
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>> Fri Oct 19 12:39:38 2012
>>> @@ -18,14 +18,36 @@
>>>   */
>>>  package org.apache.openmeetings.web.components.user.calendar;
>>>
>>> +import java.util.ArrayList;
>>> +import java.util.List;
>>> +
>>> +import
>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>> +import org.apache.openmeetings.data.conference.Roommanagement;
>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>  import org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>> +import
>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>> +import
>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>> +import org.apache.openmeetings.web.app.Application;
>>> +import org.apache.openmeetings.web.app.WebSession;
>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>  import org.apache.wicket.markup.html.form.Form;
>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>  import org.apache.wicket.markup.html.form.TextArea;
>>> +import org.apache.wicket.markup.html.form.TextField;
>>>  import org.apache.wicket.model.IModel;
>>> +import org.apache.wicket.model.PropertyModel;
>>>
>>>  public class CalendarForm extends Form<Appointment> {
>>>         private static final long serialVersionUID =
>>> -1764738237821487526L;
>>> +       private boolean createRoom = true;
>>>
>>>         public CalendarForm(String id, IModel<Appointment> model) {
>>>                 super(id, model);
>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>
>>>                 add(new RequiredTextField<String>("appointmentName"));
>>>                 add(new TextArea<String>("appointmentDescription"));
>>> +               add(new TextField<String>("appointmentLocation"));
>>> +               add(new DateTimeField("appointmentStarttime"));
>>> +               add(new DateTimeField("appointmentEndtime"));
>>> +               final PasswordTextField pwd = new
>>> PasswordTextField("password");
>>> +               pwd.setEnabled(isPwdProtected());
>>> +               pwd.setOutputMarkupId(true);
>>> +               add(pwd);
>>> +
>>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>>> +                               "remind"
>>> +                               ,
>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>> +                               , new
>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>> +
>>> +               final DropDownChoice<RoomTypes> roomType = new
>>> DropDownChoice<RoomTypes>(
>>> +                               "room.roomtype"
>>> +                               ,
>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>> +                               , new ChoiceRenderer<RoomTypes>("name",
>>> "roomtypes_id"));
>>> +               roomType.setEnabled(createRoom);
>>> +               roomType.setOutputMarkupId(true);
>>> +               add(roomType);
>>> +
>>> +               final DropDownChoice<Rooms> room = new
>>> DropDownChoice<Rooms>(
>>> +                               "room"
>>> +                               , getRoomList()
>>> +                               , new ChoiceRenderer<Rooms>("name",
>>> "rooms_id"));
>>> +               room.setEnabled(!createRoom);
>>> +               room.setOutputMarkupId(true);
>>> +               add(room);
>>> +
>>> +               add(new AjaxCheckBox("createRoom", new
>>> PropertyModel<Boolean>(this, "createRoom")) {
>>> +                       private static final long serialVersionUID =
>>> -3743113990890386035L;
>>> +
>>> +                       @Override
>>> +                       protected void onUpdate(AjaxRequestTarget
>>> target) {
>>> +                               createRoom = getConvertedInput();
>>> +
>>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>>> +                       }
>>> +               });
>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>> +                       private static final long serialVersionUID =
>>> 6041200584296439976L;
>>> +
>>> +                       @Override
>>> +                       protected void onUpdate(AjaxRequestTarget
>>> target) {
>>> +
>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>> +                               pwd.setEnabled(isPwdProtected());
>>> +                               target.add(pwd);
>>> +                       }
>>> +               });
>>> +       }
>>> +
>>> +       private boolean isPwdProtected() {
>>> +               return
>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>> +       }
>>> +
>>> +       private List<Rooms> getRoomList() {
>>> +               //FIXME need to be reviewed
>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>>> +               result.addAll(dao.getPublicRooms());
>>> +               for (Organisation_Users ou :
>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>> {
>>> +
>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>> +               }
>>> +               if (getModelObject().getRoom() != null &&
>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>> +                       result.add(getModelObject().getRoom());
>>> +               }
>>> +               return result;
>>>         }
>>>  }
>>>
>>> Modified:
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>> (original)
>>> +++
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>> Fri Oct 19 12:39:38 2012
>>> @@ -71,7 +71,7 @@
>>>                                 $('#appointment').dialog({
>>>                                         closeOnEscape: true
>>>                                         , resizable: true
>>> -                                       , width: 400
>>> +                                       , width: 450
>>>                                         , autoOpen: false
>>>                                         , modal: true
>>>                                 });
>>> @@ -89,53 +89,55 @@
>>>                                                 <td><wicket:ommessage
>>> key="572" /></td>
>>>                                                 <td><input type="text"
>>> wicket:id="appointmentName" /></td>
>>>                                         </tr>
>>> -                                       <!-- tr>
>>> -                                               <td>&nbsp;</td>
>>> -                                               <td>
>>> -
>>> <wicket:ommessage key="570" /><input type="text"
>>> wicket:id="appointmentStarttime" />
>>> -
>>> <wicket:ommessage key="571" /><input type="text"
>>> wicket:id="appointmentEndtime" />
>>> -                                               </td>
>>> +                                       <tr>
>>> +                                               <td><wicket:ommessage
>>> key="570" /></td>
>>> +                                               <td><span
>>> wicket:id="appointmentStarttime"></span></td>
>>> +                                       </tr>
>>> +                                       <tr>
>>> +                                               <td><wicket:ommessage
>>> key="571" /></td>
>>> +                                               <td><span
>>> wicket:id="appointmentEndtime"></span></td>
>>>                                         </tr>
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="565" /></td>
>>> -                                               <td><select
>>> wicket:id="notification" ></select></td>
>>> +                                               <td><select
>>> wicket:id="remind" ></select></td>
>>>                                         </tr>
>>>                                         <tr>
>>>                                                 <td colspan="2"><input
>>> type="checkbox" wicket:id="createRoom" /><wicket:ommessage key="1509"
>>> /></td>
>>>                                         </tr>
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="619" /></td>
>>> -                                               <td><select
>>> wicket:id="roomType" ></select></td>
>>> +                                               <td><select
>>> wicket:id="room.roomtype" ></select></td>
>>>                                         </tr>
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="406" /></td>
>>>                                                 <td><select
>>> wicket:id="room" ></select></td>
>>>                                         </tr>
>>>                                         <tr>
>>> -                                               <td colspan="2"><input
>>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>>> key="1509" /></td>
>>> +                                               <td colspan="2"><input
>>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>>> key="524" /></td>
>>>                                         </tr>
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="525" /></td>
>>> -                                               <td><input type="text"
>>> wicket:id="password" /></td>
>>> +                                               <td><input
>>> type="password" wicket:id="password" /></td>
>>>                                         </tr>
>>>                                         <tr>
>>>                                                 <td
>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>                                         </tr>
>>> +                                       <!--
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="803" /></td>
>>>                                                 <td><select
>>> wicket:id="meetingMember" ></select></td>
>>> -                                       </tr>
>>> +                                       </tr -->
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="569" /></td>
>>>                                                 <td><input type="text"
>>> wicket:id="appointmentLocation" /></td>
>>> -                                       </tr-->
>>> +                                       </tr>
>>>                                         <tr>
>>>                                                 <td><wicket:ommessage
>>> key="573" /></td>
>>> -                                               <td><input type="text"
>>> wicket:id="appointmentDescription" /></td>
>>> +                                               <td><textarea
>>> wicket:id="appointmentDescription"></textarea></td>
>>>                                         </tr>
>>>                                         <!-- tr>
>>>                                                 <td colspan="2"
>>> style="text-align: right"><input type="button" wicket:id="save" /><input
>>> type="button" wicket:id="cancel" /></td>
>>> -                                       </tr-->
>>> +                                       </tr -->
>>>                                 </table>
>>>                         </form>
>>>                 </div>
>>>
>>> Modified:
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>> (original)
>>> +++
>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>> Fri Oct 19 12:39:38 2012
>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>                                 Calendar end = WebSession.getCalendar();
>>>
>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>
>>> +                               if (start.equals(end)) {
>>> +                                       end.add(Calendar.HOUR_OF_DAY, 1);
>>> +                               }
>>>                                 Appointment a = new Appointment();
>>>
>>> a.setAppointmentStarttime(start.getTime());
>>>                                 a.setAppointmentEndtime(end.getTime());
>>>
>>>
>>>
>>
>>
>> --
>> Sebastian Wagner
>> https://twitter.com/#!/dead_lock
>> http://www.webbase-design.de
>> http://www.wagner-sebastian.com
>> seba.wagner@gmail.com
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>
>
>

Re: svn commit: r1400075 - in /incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings: data/conference/ persistence/beans/rooms/ web/components/user/calendar/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
I guess this happened lately in trunk.
How are we the in the future planning to determine the current users in the
room.
Session or database based?

I ask that critical as some queries require to sync messages to all clients
of a room.
This can happen 1000 times in a single second if you think about having up
to 1000 concurrent user sessions.

For example:
ScopeApplicationAdapter::syncMessageToCurrentScope(String remoteMethodName,
Object newMessage, boolean sendSelf, boolean sendScreen)
=> Collection<Set<IConnection>> conCollection = current.getScope()
                    .getConnections();
==> iterates through all connection of the scope.

Now the new thing is that for every connection you will create a query for
the RoomClient Object.
This is simply impossible.

We want to scale up to 1000 concurrent user sessions and more.
The RoomClient is a typical Session object and it should stay in the
session.
It is the same issue like with the WhiteboardObject.
We are making a real time application, there is no chance to run queries in
sync methods.

Can we find some consens here? I know you must have refactored already a
lot but I strictly did implement zero db related stuff in sync methods.

There might be a chance for some events to trigger db actions.However I
don't think having two times the RoomClient stored (one time session,
second time database) makes sense.

What are you thoughts on this?

Sebastian

2012/10/19 seba.wagner@gmail.com <se...@gmail.com>

> Hi Maxim,
>
> I don't understand this new code in the Rooms Entity:
>     @OneToMany(fetch = FetchType.LAZY)
>
>     @JoinColumn(name = "room_id")
>     private List<RoomClient> currentusers;
>
> We calc the current users online by iterating through the Red5 Connections.
> In which OpenMeetings version was it changed?
>
> I guess you can set it Transient for XML export/import. So maybe annotate
> it with:
> @org.simpleframework.xml.Transient
> same like roomOrganisations.
>
> Sebastian
>
> 2012/10/19 <so...@apache.org>
>
>  Author: solomax
>> Date: Fri Oct 19 12:39:38 2012
>> New Revision: 1400075
>>
>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>> Log:
>> Wicket: calendar form is improved
>>
>> Modified:
>>
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>
>> Modified:
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>> (original)
>> +++
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>> Fri Oct 19 12:39:38 2012
>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>                 return q.getSingleResult();
>>         }
>>
>> +       public List<Rooms> getPublicRooms() {
>> +               //TypedQuery<Rooms> q =
>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>> +               TypedQuery<Rooms> q = em.createQuery(
>> +                               "SELECT r from Rooms r LEFT JOIN FETCH
>> r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY
>> r.name ASC", Rooms.class);
>> +               return q.getResultList();
>> +       }
>> +
>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>> +               TypedQuery<Rooms> q = em.createQuery(
>> +                               "SELECT DISTINCT c.room FROM
>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>> c.room.currentusers "
>> +               + "WHERE c.organisation.organisation_id = :orgId "
>> +               + "AND c.deleted = false AND c.room.deleted = false "
>> +               + "AND c.organisation.deleted = false "
>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>> +               q.setParameter("orgId", orgId);
>> +               return q.getResultList();
>> +       }
>> +
>>         public Rooms update(Rooms entity, long userId) {
>>                 if (entity.getRooms_id() == null) {
>>                 /* Red5SIP integration
>> *******************************************************************************/
>>
>> Modified:
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>> (original)
>> +++
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>> Fri Oct 19 12:39:38 2012
>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>  import javax.persistence.OneToMany;
>>  import javax.persistence.OneToOne;
>>  import javax.persistence.Table;
>> -import javax.persistence.Transient;
>>
>>  import org.apache.openjpa.persistence.ElementDependent;
>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>         private String name;
>>
>>         @Lob
>> -       // @Basic(fetch=FetchType.LAZY)
>>         @Column(name = "comment_field")
>>         @Element(data = true, required = false)
>>         private String comment;
>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>         @org.simpleframework.xml.Transient
>>         private List<Rooms_Organisation> roomOrganisations = new
>> ArrayList<Rooms_Organisation>();
>>
>> -       /*
>> -        * Non persistent attributes
>> -        */
>> -       @Transient
>> +       @OneToMany(fetch = FetchType.LAZY)
>> +       @JoinColumn(name = "room_id")
>>         private List<RoomClient> currentusers;
>>
>>         public String getComment() {
>>
>> Modified:
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>> (original)
>> +++
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>> Fri Oct 19 12:39:38 2012
>> @@ -18,14 +18,36 @@
>>   */
>>  package org.apache.openmeetings.web.components.user.calendar;
>>
>> +import java.util.ArrayList;
>> +import java.util.List;
>> +
>> +import
>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>> +import org.apache.openmeetings.data.conference.RoomDAO;
>> +import org.apache.openmeetings.data.conference.Roommanagement;
>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>  import org.apache.openmeetings.persistence.beans.calendar.Appointment;
>> +import
>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>> +import
>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms;
>> +import org.apache.openmeetings.web.app.Application;
>> +import org.apache.openmeetings.web.app.WebSession;
>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField;
>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>  import org.apache.wicket.markup.html.form.Form;
>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>  import org.apache.wicket.markup.html.form.TextArea;
>> +import org.apache.wicket.markup.html.form.TextField;
>>  import org.apache.wicket.model.IModel;
>> +import org.apache.wicket.model.PropertyModel;
>>
>>  public class CalendarForm extends Form<Appointment> {
>>         private static final long serialVersionUID =
>> -1764738237821487526L;
>> +       private boolean createRoom = true;
>>
>>         public CalendarForm(String id, IModel<Appointment> model) {
>>                 super(id, model);
>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>
>>                 add(new RequiredTextField<String>("appointmentName"));
>>                 add(new TextArea<String>("appointmentDescription"));
>> +               add(new TextField<String>("appointmentLocation"));
>> +               add(new DateTimeField("appointmentStarttime"));
>> +               add(new DateTimeField("appointmentEndtime"));
>> +               final PasswordTextField pwd = new
>> PasswordTextField("password");
>> +               pwd.setEnabled(isPwdProtected());
>> +               pwd.setOutputMarkupId(true);
>> +               add(pwd);
>> +
>> +               add(new DropDownChoice<AppointmentReminderTyps>(
>> +                               "remind"
>> +                               ,
>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>> +                               , new
>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>> +
>> +               final DropDownChoice<RoomTypes> roomType = new
>> DropDownChoice<RoomTypes>(
>> +                               "room.roomtype"
>> +                               ,
>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>> +                               , new ChoiceRenderer<RoomTypes>("name",
>> "roomtypes_id"));
>> +               roomType.setEnabled(createRoom);
>> +               roomType.setOutputMarkupId(true);
>> +               add(roomType);
>> +
>> +               final DropDownChoice<Rooms> room = new
>> DropDownChoice<Rooms>(
>> +                               "room"
>> +                               , getRoomList()
>> +                               , new ChoiceRenderer<Rooms>("name",
>> "rooms_id"));
>> +               room.setEnabled(!createRoom);
>> +               room.setOutputMarkupId(true);
>> +               add(room);
>> +
>> +               add(new AjaxCheckBox("createRoom", new
>> PropertyModel<Boolean>(this, "createRoom")) {
>> +                       private static final long serialVersionUID =
>> -3743113990890386035L;
>> +
>> +                       @Override
>> +                       protected void onUpdate(AjaxRequestTarget target)
>> {
>> +                               createRoom = getConvertedInput();
>> +
>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom));
>> +                       }
>> +               });
>> +               add(new AjaxCheckBox("isPasswordProtected") {
>> +                       private static final long serialVersionUID =
>> 6041200584296439976L;
>> +
>> +                       @Override
>> +                       protected void onUpdate(AjaxRequestTarget target)
>> {
>> +
>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>> +                               pwd.setEnabled(isPwdProtected());
>> +                               target.add(pwd);
>> +                       }
>> +               });
>> +       }
>> +
>> +       private boolean isPwdProtected() {
>> +               return
>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>> +       }
>> +
>> +       private List<Rooms> getRoomList() {
>> +               //FIXME need to be reviewed
>> +               List<Rooms> result = new ArrayList<Rooms>();
>> +               RoomDAO dao = Application.getBean(RoomDAO.class);
>> +               result.addAll(dao.getPublicRooms());
>> +               for (Organisation_Users ou :
>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>> {
>> +
>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>> +               }
>> +               if (getModelObject().getRoom() != null &&
>> getModelObject().getRoom().getAppointment()) { //FIXME review
>> +                       result.add(getModelObject().getRoom());
>> +               }
>> +               return result;
>>         }
>>  }
>>
>> Modified:
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>> URL:
>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>> (original)
>> +++
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>> Fri Oct 19 12:39:38 2012
>> @@ -71,7 +71,7 @@
>>                                 $('#appointment').dialog({
>>                                         closeOnEscape: true
>>                                         , resizable: true
>> -                                       , width: 400
>> +                                       , width: 450
>>                                         , autoOpen: false
>>                                         , modal: true
>>                                 });
>> @@ -89,53 +89,55 @@
>>                                                 <td><wicket:ommessage
>> key="572" /></td>
>>                                                 <td><input type="text"
>> wicket:id="appointmentName" /></td>
>>                                         </tr>
>> -                                       <!-- tr>
>> -                                               <td>&nbsp;</td>
>> -                                               <td>
>> -                                                       <wicket:ommessage
>> key="570" /><input type="text" wicket:id="appointmentStarttime" />
>> -                                                       <wicket:ommessage
>> key="571" /><input type="text" wicket:id="appointmentEndtime" />
>> -                                               </td>
>> +                                       <tr>
>> +                                               <td><wicket:ommessage
>> key="570" /></td>
>> +                                               <td><span
>> wicket:id="appointmentStarttime"></span></td>
>> +                                       </tr>
>> +                                       <tr>
>> +                                               <td><wicket:ommessage
>> key="571" /></td>
>> +                                               <td><span
>> wicket:id="appointmentEndtime"></span></td>
>>                                         </tr>
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="565" /></td>
>> -                                               <td><select
>> wicket:id="notification" ></select></td>
>> +                                               <td><select
>> wicket:id="remind" ></select></td>
>>                                         </tr>
>>                                         <tr>
>>                                                 <td colspan="2"><input
>> type="checkbox" wicket:id="createRoom" /><wicket:ommessage key="1509"
>> /></td>
>>                                         </tr>
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="619" /></td>
>> -                                               <td><select
>> wicket:id="roomType" ></select></td>
>> +                                               <td><select
>> wicket:id="room.roomtype" ></select></td>
>>                                         </tr>
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="406" /></td>
>>                                                 <td><select
>> wicket:id="room" ></select></td>
>>                                         </tr>
>>                                         <tr>
>> -                                               <td colspan="2"><input
>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>> key="1509" /></td>
>> +                                               <td colspan="2"><input
>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage
>> key="524" /></td>
>>                                         </tr>
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="525" /></td>
>> -                                               <td><input type="text"
>> wicket:id="password" /></td>
>> +                                               <td><input
>> type="password" wicket:id="password" /></td>
>>                                         </tr>
>>                                         <tr>
>>                                                 <td
>> colspan="2"><wicket:ommessage key="1445" /></td>
>>                                         </tr>
>> +                                       <!--
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="803" /></td>
>>                                                 <td><select
>> wicket:id="meetingMember" ></select></td>
>> -                                       </tr>
>> +                                       </tr -->
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="569" /></td>
>>                                                 <td><input type="text"
>> wicket:id="appointmentLocation" /></td>
>> -                                       </tr-->
>> +                                       </tr>
>>                                         <tr>
>>                                                 <td><wicket:ommessage
>> key="573" /></td>
>> -                                               <td><input type="text"
>> wicket:id="appointmentDescription" /></td>
>> +                                               <td><textarea
>> wicket:id="appointmentDescription"></textarea></td>
>>                                         </tr>
>>                                         <!-- tr>
>>                                                 <td colspan="2"
>> style="text-align: right"><input type="button" wicket:id="save" /><input
>> type="button" wicket:id="cancel" /></td>
>> -                                       </tr-->
>> +                                       </tr -->
>>                                 </table>
>>                         </form>
>>                 </div>
>>
>> Modified:
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>> (original)
>> +++
>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>> Fri Oct 19 12:39:38 2012
>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>                                 Calendar end = WebSession.getCalendar();
>>
>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>
>> +                               if (start.equals(end)) {
>> +                                       end.add(Calendar.HOUR_OF_DAY, 1);
>> +                               }
>>                                 Appointment a = new Appointment();
>>
>> a.setAppointmentStarttime(start.getTime());
>>                                 a.setAppointmentEndtime(end.getTime());
>>
>>
>>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com