1 2 Previous Next 17 Replies Latest reply on Feb 4, 2009 5:22 AM by clerum

    Client IP Address

    clerum

      I'm trying to add some code to my app which will log a message to the database for certain key action. I want it to be injectable so that anywhere in my app I can go


      @In ELog elog;
      
      then...
      
      elog.addLog("This is a test log message);



      One of the variables that I want to be able to write to the db is the clients IP Address. I show this value on my homepage via the #{request.remoteAddr}


      However I don't understand how to get that variable from within my Java Code..


      package net.domain.demo;
      
      import java.util.GregorianCalendar;
      import java.util.TimeZone;
      
      import javax.ejb.Remove;
      import javax.ejb.Stateful;
      import javax.persistence.EntityManager;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Scope;
      
      @Name("elog")
      @Stateful
      @Scope(ScopeType.SESSION)
      public class ELogBean implements ELog {
           
           @In(required=false)
           ActiveUser activeuser;
           
           EntityManager em;
           
           public ELogBean(EntityManager em) 
           {
                this.em = em;
           }
           
           public void addLog(String type, String msg)
           {
                System.out.println("Adding Log for IP: #{request.remoteAddr}");
                GregorianCalendar now = (GregorianCalendar) GregorianCalendar.getInstance();
                System.out.println("Adding log at:" + now.getTimeInMillis());
                EventLog newlog = new EventLog(activeuser.getUser(),type,msg,"#{request.remoteAddr}",now);
                em.persist(newlog);
           }
           
           public void addLogEarly(User user, String type, String msg)
           {
                GregorianCalendar now = (GregorianCalendar) GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
                EventLog newlog = new EventLog(user,type,msg,"#{request.remoteAddr}",now);
                System.out.println("Adding Log for " + newlog.getUser().getUsername());
                System.out.println("Adding Log for " + newlog.getType());
                System.out.println("Adding Log for " + newlog.getMsg());
                System.out.println("Adding Log for " + newlog.getIpaddr());
                System.out.println("Adding Log for" + newlog.getTime().toString());
                if(em == null)
                {
                     System.out.println("Entity Manager is Null!!!!");
                }
                else
                {
                     em.persist(newlog);
                }
           }
           
           @Remove
          public void destroy() 
          {
               
          }
           
      }
      



      #{request.remoteAddr} is literally what is persisted to the database. Also I don't see where request is defined in the components.xml so I don't know what Class I would event Inject it as.


      Anyone run into this before?

        • 1. Re: Client IP Address
          www.supernovasoftware.com

              @In private FacesContext facesContext;   
          
              public String example() 
              {
                return ((HttpServletRequest) facesContext.getExternalContext().getRequest()).getRemoteAddr();
              } 





          • 2. Re: Client IP Address
            clerum

            Thanks that does work from my login method which is called from the webpage but my logging method which is in another object called from the login method just gets a null for it...is that object only available on level deep or am I missing something bigger?

            • 3. Re: Client IP Address
              www.supernovasoftware.com

              I use a Phase listener to do logging and it always works.



                   public void beforePhase(PhaseEvent event) 
                   {
                        if(event.getPhaseId()==PhaseId.RESTORE_VIEW)
                              {
                          HttpServletRequest request = (HttpServletRequest)event.getFacesContext().getExternalContext().getRequest();
                          Access access = new Access();
                          access.setAddressIP(request.getRemoteAddr());
                           }          
                   }



              Not sure why you would be getting null.  What is the scope of the loggin object?

              • 4. Re: Client IP Address
                clerum

                It's of the session scope.


                Seems that if I call another method in a object different than the one I initially called from the web site I can't inject things.

                • 5. Re: Client IP Address
                  www.supernovasoftware.com

                  Does this object lack @Name(xxxxxxx) or have @BypassInterceptors?


                  Try another scope and see if that helps.

                  • 6. Re: Client IP Address
                    clerum

                    No it's all really generic.


                    Here is an example.


                    I call

                    <s:link id="viewOpp" value="View Details" action="#{sfopportunity.selectOpportunity(opp)}"/>

                    from my page which list opportunities.


                    Which hits


                    @Stateful
                    @Name("sfopportunity")
                    public class SFOpportunityBean implements SFOpportunity {
                         
                         @In(create=true, required=true)
                         @Out(scope=ScopeType.SESSION)
                         private SFConnection sfc; 
                         
                         @In
                         ActiveUser activeuser;
                         
                         @In(required=false)
                         @Out(required=false)
                         Opportunity opp;
                         
                         @DataModel
                         private Collection <Opportunity> oppList = new ArrayList<Opportunity>();
                         
                         @Factory("oppList")
                         public void listOpportunities()
                         {     
                              
                              QueryResult qr = null;
                              String query = "Select o.AccountId, o.Account.Name,o.Account.Id,o.Amount, o.ChannelPartner__c, o.ChannelPartner__r.AccountCode__c, o.CloseDate, o.CreatedDate, o.Id, o.LastActivityDate, o.Name, o.OfferValidUntil__c, o.OwnerId, o.Owner.Email, o.Owner.Name, o.Partner_Account_Manager__c, o.Partner_Quote_Received__c, o.StageName from Opportunity o where o.ChannelPartner__r.AccountCode__c ='" + activeuser.getUser().getOrganization().getSfcode() + "' and isClosed = false";
                            qr = sfc.runQuery(query);       
                              oppList.clear();
                            if (qr.getSize() != 0) 
                            {
                                 for(int x=0; x<qr.getSize(); x++)
                                 {
                                      Opportunity op = (Opportunity) qr.getRecords(x);
                                     oppList.add(op);
                                 }
                            }
                         }
                         
                         public String selectOpportunity(Opportunity selectedOpp)
                         {
                              opp = selectedOpp;
                              SFSiteBean sfb = new SFSiteBean();
                              sfb.listSitesByAccount(opp.getAccount());
                              return "/partner/opp_view.xhtml";
                         }
                         
                       @Remove
                       public void destroy() {}     
                    }
                    



                    Everything in that Class works fine. I can inject and outject just fine. But my code is calling sfb.listSitesByAccount which goes here


                    @Stateful
                    @Name("sfsite")
                    public class SFSiteBean implements SFSite {
                         
                         @In(create=true, required=true)
                         private SFConnection sfc;      
                         
                         @DataModel
                         private Collection <Site__c> siteList = new ArrayList<Site__c>();
                         
                         @In 
                         ELogBean elog;
                         
                         @Factory("siteList")
                         public void listSitesByAccount(Account acct)
                         {
                              if(elog == null) { System.out.println("elog is NULL!"); }
                              else 
                              {
                                   elog.addLog("salesforce", ("Querying Sites for Account: " + acct.getName()));
                              }
                              System.out.println("Print sites for Account " + acct.getName());
                              QueryResult qr = null;
                              String query = "Select s.Account__c, s.Id, s.Name, s.PBX_Interface__c, s.PBX_Interface_Type__c, s.PBX_Manuf__c, s.PBX_Notes__c, s.PBX_Support_Contact__c, s.PBXLOC__c, s.Site_Notes__c, s.State__c, s.Street__c, s.ZIP__c from Site__c s where s.Account__r.Id='" +acct.getId() + "'";
                              System.out.println("Got past building the Query");
                              System.out.println(query);
                              if(sfc == null) { System.out.println("sfc is NULL!"); }
                            qr = sfc.runQuery(query);
                              System.out.println("Got past running the Query");
                              siteList.clear();
                              System.out.println("Got past clearing the Query");
                    
                            if (qr.getSize() != 0) 
                            {
                                 System.out.println("Query got: " + qr.getSize());
                                 for(int x=0; x<qr.getSize(); x++)
                                 {
                                      Site__c st = (Site__c) qr.getRecords(x);
                                     siteList.add(st);
                                 }
                            }
                              
                         }
                           
                         @Remove
                         public void destroy() {}     
                    
                    }
                    



                    Once my code start executing here I am dead in the water.


                    16:39:53,096 INFO  [STDOUT] Print sites for Account Black Mountain Associates
                    16:39:53,096 INFO  [STDOUT] Got past building the Query
                    16:39:53,096 INFO  [STDOUT] Select s.Account__c, s.Id, s.Name, s.PBX_Interface__c, s.PBX_Interface_Type__c, s.PBX_Manuf__c, s.PBX_Notes__c, s.PBX_Support_Contact__c, s.PBXLOC__c, s.Site_Notes__c, s.State__c, s.Street__c, s.ZIP__c from Site__c s where s.Account__r.Id='001S0000004DXiwIAG'
                    16:39:53,096 INFO  [STDOUT] sfc is NULL!
                    



                    Variables I pass in through in methods like the Account are fine but anything injected like elog or sfc are null.


                    The only thing different here is that this is one level deeper than the methods called from my web pages.


                    What am I doing wrong?



                    • 7. Re: Client IP Address
                      www.supernovasoftware.com

                      Not sure.  Could be the naming of your components.  What are the names of ELogBean and SFConnection?

                      • 8. Re: Client IP Address
                        clerum

                        elog and sfc respectivly

                        • 9. Re: Client IP Address
                          clerum

                          I'm thinking I need to proxy these calls through Component.getInstance()    but not sure yet. I'll follow back up with the thread when I get it working.

                          • 10. Re: Client IP Address
                            www.supernovasoftware.com

                            I have no problem injecting on multiple levels.  One thing that I seem to remember was naming according to Java conventions.  I seem to remember some problem with this for me before, but I am not sure it was with Seam.  Now I name thing as such. 



                            @In
                            CustomerPO customerPO;




                            instead of



                            @In
                            POCustomer poCustomer;




                            It could have something to do with reflection.


                            I might be talking out of my ass, but it should be easy enough for you to verify.


                            Let me know what you find.

                            • 11. Re: Client IP Address
                              clerum

                              I just got it a few minutes ago.


                              The issue as I found in Seam in action on page 244 is these are internal method calls and this bijection will not occur. It will only occur on methods that seam intercepts...which makes total sense now.


                              For those who find this later when searching the forums...





                              public String selectOpportunity(Opportunity selectedOpp)
                                   {
                                        opp = selectedOpp;
                                        SFSite sfb = (SFSite) Component.getInstance("sfsite", ScopeType.EVENT);
                                        sfb.listSitesByAccount(opp.getAccount());
                                        
                                        return "/partner/opp_view.xhtml";
                                   }
                              



                              That causes the sfb to be created by seam rather than the constructor on the class and thus bijection takes place.

                              • 12. Re: Client IP Address
                                www.supernovasoftware.com

                                I still do not follow.  I have only had to use Component.getInstance in servlets or converters or components with @BypassInterceptors.


                                What was different about this component that it could not be injected?


                                Since you did not specify a scope on SFSiteBean it should default to Conversation.


                                And components without scope specified will be taken from the scope specified on the component.


                                You use event scope for SFSite.


                                Maybe you could specify the scope in the @In for SFSiteBean and it would work.

                                • 13. Re: Client IP Address
                                  clerum

                                  From what I read, the SFSiteBean object would be created but bijection would not occur because it was created via an internal method call....which is not intercepted.


                                  Because of this all my @In object/variables were null.


                                  The issue wasn't that the component couldn't be injected...it can. The issue is that bijection was never triggered due to how the object was created.


                                  follow?

                                  • 14. Re: Client IP Address
                                    www.supernovasoftware.com

                                    I can see if you created the component like


                                    SFSite sfb = new SFSite();  



                                    , but it looks like you were injecting it.


                                    How were you creating it other than using



                                    @In



                                    1 2 Previous Next