Tuesday 24 November 2015

Install MongoDB on Windows & Knowledge

https://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/

http://robomongo.org/

Spring and Mongodb Integration


Step-1

Add below dependency  inside the pom.xml

                 <dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>

Step-2
Annotate the pojo used in mongodb as shown below

@Document(collection="person")
public class Person {

@Id
private String id;
private String name;

public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}


Step-3
Define "mongoTemplate"  as shown below

<!-- Factory bean that creates the Mongo instance -->
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
<property name="host" value="localhost" />
</bean>

<!-- MongoTemplate for connecting and quering the documents in the database -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongo" ref="mongo" />
<constructor-arg name="databaseName" value="synergy-bank-app" />
</bean>

<!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes -->

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />


Step-4
autowired above mongoTemplate inside the dao layer.............


@Repository
public class PersonService {

@Autowired
private MongoTemplate mongoTemplate;

public static final String COLLECTION_NAME = "person";

public void addPerson(Person person) {
if (!mongoTemplate.collectionExists(Person.class)) {
mongoTemplate.createCollection(Person.class);
}
person.setId(UUID.randomUUID().toString());
mongoTemplate.insert(person, COLLECTION_NAME);
}

public List<Person> listPerson() {
return mongoTemplate.findAll(Person.class, COLLECTION_NAME);
}

public List<Person> findPersonByName(String name) {
Query query = new Query();
query.addCriteria(Criteria.where("name").is(name));
return mongoTemplate.find(query, Person.class, COLLECTION_NAME);
}


public void deletePerson(Person person) {
mongoTemplate.remove(person, COLLECTION_NAME);
}

public void updatePerson(Person person) {
mongoTemplate.insert(person, COLLECTION_NAME);
}

public static void main(String[] args) {
System.out.println(UUID.randomUUID().toString());
}

}


Command to start the mongodb
D:\mongodb\bin>mongod -d dbpath=c:\mongodb\data

dbpath= must be there to start the server


Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.

C:\Users\cool>d:

D:\>cd mongodb

D:\mongodb>cd bin

D:\mongodb\bin>mongo.exe
MongoDB shell version: 2.6.11-pre-
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        http://docs.mongodb.org/
Questions? Try the support group
        http://groups.google.com/group/mongodb-user
> show dbs;
admin  (empty)
local  0.078GB
> use nagen
switched to db nagen
> db
nagen
> show dbs;
admin  (empty)
local  0.078GB
> db
nagen
> show dbs;
admin  (empty)
local  0.078GB
> show dbs;
admin             (empty)
local             0.078GB
synergy-bank-app  0.078GB
> show dbs;
admin             (empty)
local             0.078GB
synergy-bank-app  0.078GB
> show dbs;
admin             (empty)
local             0.078GB
synergy-bank-app  0.078GB
> use synergy-bank-app
switched to db synergy-bank-app
>




Difference Between @Resource, @Autowired and @Inject in Spring Injection


  1. @Resource – Defined in the javax.annotation package and part of Java
  2. @Inject – Defined in the javax.inject package and part of Java
  3. @Autowired – Defined in the package org.springframework.bean.factory and part of Spring framework.

@Autowired and Inject behaves exactly same

Order is  -> byType -> @Qualifier ->byName





@Service

public class FruitProcessor {

@Autowired
private Fruit fruit;
//private Fruit fruit;
//private Fruit fruit;
}

@Service
public class FruitProcessor {

@Resource
@Qualifier("mango")
private Fruit apple;
//private Fruit fruit;
//private Fruit fruit;

@Override
public String toString() {
return "FruitProcessor [apple=" + apple + "]";
}

}

output is :
FruitProcessor [apple=Apple [taste=sour, getColor()=null]]

Means still we mentioned @Qualifier("mango") but it is autowired by
byName

Because Autowiring  order for @Resource  is -byName -> byType->@Qualifier

Summary :-
@Autowired and @Inject
  1. Matches by Type
  2. Restricts by Qualifiers
  3. Matches by Name
@Resource
  1. Matches by Name
  2. Matches by Type
  3. Restricts by Qualifiers (ignored if match is found by name)

Monday 23 November 2015

Sending Email using Spring Framework


Step-1

Add dependency

<!-- Spring API for mailing support org.springframework.mail.javamail.JavaMailSenderImpl --> 
        <dependency> 
               <groupId>org.springframework</groupId> 
                <artifactId>spring-context-support</artifactId>
               <version>${spring.version}</version> 
            </dependency>

<!-- Java Mail API -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.3</version>

</dependency>


Step-2
create spring meta configuration file..
spring-email-service.xml

  <bean id="synergyMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" lazy-init="true">
        <property name="host" value="smtp.gmail.com"/>
        <property name="port" value="587"/>
        <property name="username" value="coolcool@gmail.com"/>
        <property name="password" value="desibank"/>
        <property name="javaMailProperties">
            <props>
                <!-- Use SMTP transport protocol -->
                <prop key="mail.transport.protocol">smtp</prop>
                <!-- Use SMTP-AUTH to authenticate to SMTP server -->
                <prop key="mail.smtp.auth">true</prop>
                <!-- Use TLS to encrypt communication with SMTP server -->
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.debug">false</prop>
            </props>
        </property>

    </bean>


Step-3

Define the interface

/**
 * 
 * @author nagendra.yadav
 *
 */
public interface BankEmailService {

public void sendMail(String from,String to,String subject,String body);
public void sendMail(String from, String[] to, String subject, String body);
public void sendBirthdayEmails(String from, String to, String subject,
String body, String name);


}


Step-4
Write Service Implementation

import org.springframework.mail.javamail.JavaMailSender;

@Service("BankEmailServiceImpl")
public class BankEmailServiceImpl implements BankEmailService {

@Autowired
@Qualifier("synergyMailSender")
private JavaMailSender mailSender;

@Override
public void sendMail(String from, String to, String subject, String body) {
        SimpleMailMessage message = new SimpleMailMessage();
       message.setFrom(from);
       message.setTo(to);
       message.setSubject(subject);
       message.setText(body);
       mailSender.send(message);
}

@Override
public void sendMail(String from, String[] to, String subject, String body) {
   SimpleMailMessage message = new SimpleMailMessage();
           message.setFrom(from);
           message.setTo(to);
           message.setSubject(subject);
           message.setText(body);
           mailSender.send(message);

}

}


Step-5
Sending email using thread to make it asynchronous 

public class EmailSenderThread extends Thread {

private  BankEmailService bankEmailService;
private String toEMail;
private String message;
private String subject;

public EmailSenderThread(BankEmailService bankEmailService, String toEMail,
String message,String subject) {
this.bankEmailService = bankEmailService;
this.toEMail = toEMail;
this.message = message;
this.subject=subject;
}

public EmailSenderThread(String tname){
 super(tname);
}

public void run() {
try {
bankEmailService.sendMail("cool@gmail.com",toEMail,subject,message);
}catch (Exception e) {
e.printStackTrace();
}
}

}


Step-6

Send the email using below code

EmailSenderThread emailSenderThread = new EmailSenderThread(
bankEmailService,
customerAccountForm.getCustomerEmail(), body,
"Account creation notification !");

emailSenderThread.start();



Friday 20 November 2015

Under what conditions is a JSESSIONID created?


JSESSIONID cookie is created/sent when session is created. Session is created when your 
code calls request.getSession() or request.getSession(true) for the first time. 
If you just want get session, but not create it if it doesn't exists, 
use request.getSession(false) -- this will return you a session or null. In this case, new session is not created, and JSESSIONID cookie is not sent. (This also means 
that session isn't necessarily created on first request... you and your code is in control when the session is created)


HttpSession objects must be scoped at the application (or servlet context) level. The 
underlying mechanism, such as the cookie used to establish the session, can be the same 

for different contexts, but the object referenced, including the attributes in that object, 
must never be shared between contexts by the container.

What is the use case for overriding default login-processing-url in spring security


By default, the logout process will first invalidate the session, hence triggering the session management to redirect to the invalid session page. By specifying invalidate-session="false" will fix this behavior.
<sec:logout logout-success-url="/logout" invalidate-session="false" 
delete-cookies="JSESSIONID" />


Thursday 19 November 2015

Spring Security Implementation in Project

Step-1 

Add dependency for Spring Security inside the pom.xml

<!-- Below two dependency are for Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>

</dependency>

Step-2
Configure the filter for spring security

         <filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter> 

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>

</filter-mapping> 


Note : springSecurityFilterChain -> filter name we cannot change since this is the name of
of spring bean which is responsible for spring security.


Step-3
Design Login Page for Spring Security

URI to open this page...............

login-page="/bank/auth"

@RequestMapping(value = "/auth", method = RequestMethod.GET)
public String auth(Model model,HttpServletRequest request) {
String userAgent = request.getHeader("User-Agent");
System.out.println("_____userAgent____  = "+userAgent);
model.addAttribute("applicationMessage",
"Please Log in using your credentials!");
return NavigationConstant.COMMON_PAGE +
               NavigationConstant.LOGIN_PAGE;

}

 <form method="post" action="../j_spring_security_check">
        <p><input type="text" name="j_username"  id="loginId" value="" placeholder="Bank userid"></p>
        <p><input type="password" id="password" name="j_password" value="" placeholder="Password"></p>
        <p >
     <!--   <input type="button" name="commit" style="background: url(images/logs.jpg); width:100px; height:35px;" />         -->
     <a href="${pageContext.request.contextPath}/bank/customerRegistration">
      Sign Up 
         <button type="button" class="btn" id="signid" style="width:140px;background-color:#156AEB;color:white;">Login</button>
        </p>

      </form>



Step-4
Create Spring security meta configuration file

    <!-- <security:global-method-security pre-post-annotations="enabled" proxy-target-class="true"/>  -->              
<!-- This is where we configure Spring-Security  -->
<security:http auto-config="true" use-expressions="true" access-denied-page="/bank/auth/denied" >

     <security:intercept-url pattern="/bank/customerRegistration" access="permitAll"/>

    <security:intercept-url pattern="/bank/lockUnlockCustomers" access="permitAll"/>
     <security:intercept-url pattern="/bank/auth" access="permitAll"/>
     <security:intercept-url pattern="/MTID/**" access="permitAll"/>
      <security:intercept-url pattern="/bank/logout" access="permitAll"/>
      <security:intercept-url pattern="/auth/register.htm" access="permitAll"/>


<security:intercept-url pattern="/bank/**" access="hasRole('admin')"/>

<security:intercept-url pattern="/bank/**" access="hasAnyRole('admin','customer')"/>
<!-- Below three are not in use so far -->
<security:intercept-url pattern="/customer/**" access="hasRole('customer')"/>
<security:intercept-url pattern="/admin/**" access="hasRole('admin')"/>
<security:intercept-url pattern="/common/**" access="hasAnyRole('admin','user')"/>

 <security:form-login login-page="/bank/auth"
authentication-failure-url="/bank/invalidLogin" 
default-target-url="/bank/homescreen.htm"/>

<security:logout 
invalidate-session="true" 
logout-success-url="/bank/auth" 
logout-url="/auth/logout.htm"/>


</security:http>


Step-5

<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
       <security:authentication-provider user-service-ref="customUserDetailsService"><!--
        <security:password-encoder ref="passwordEncoder"/>
       --></security:authentication-provider>

</security:authentication-manager>


Step-6

@Transactional(readOnly = true)
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

protected static Logger logger = Logger.getLogger(CustomUserDetailsService.class);

@Autowired
@Qualifier("BankAuthServiceImpl")
private BankAuthService bankAuthService;

/**
* Retrieves a user record containing the user's credentials and access. 
*/
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
// Declare a null Spring User
UserDetails user = null;
         try {

LoginForm loginForm=bankAuthService.findLoginDetailByUserName(username);
          
           user =  new User(
loginForm.getUserId(), 
loginForm.getPassword(),
true,
true,
true,
true,

getAuthorities(loginForm.getRole()) );
    
      }


When user object is return from this method loadUserByUsername then userid and password will be matched with html form ..

if it is not valid ????? 
authentication-failure-url="/bank/invalidLogin" 

if it is valid ????? 
default-target-url="/bank/homescreen.htm"/>

Step-7

@RequestMapping(value="homescreen.htm",method = RequestMethod.GET)
public String handleRequestInternalModel model) throws Exception {

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

  //here we are accessing for logged in user
 Collection<? extends GrantedAuthority> grantedList=authentication.getAuthorities();

if(grantedList!=null && grantedList.size()>0){
        Iterator<? extends GrantedAuthority> iterator=grantedList.iterator();
        if(iterator.hasNext()){
        GrantedAuthority ga=iterator.next();
           nextPage=ga.getAuthority(); //admin,user
        }

        }



 //Here setting data inside the user session
 LoginForm dLoginForm=bankAuthService.findLoginDetailByUserName(authentication.getName());

HttpSession session=request.getSession();
    session.setAttribute(NavigationConstant.USER_SESSION_DATA,

loginForm);// Storing session information

if(nextPage.equals(RoleContant.CUSTOMER.getValue())){
return NavigationConstant.CUSTOMER_PAGE
+ NavigationConstant.CUSTOMER_HOME_PAGE;
}else{
List<String> imagePathList = bankAuthService.imageAdminSliderList();
model.addAttribute("imageList", imagePathList);
return NavigationConstant.ADMIN_PAGE
+ NavigationConstant.ADMIN_HOME_PAGE;

}

}


Step-8

HOME PAGE AFTER AUTHENTICATION

    Spring Security Flow  ->>
    

When we clicked  some other link to access the page

Example below link
http://localhost:5050/synergy-bank/bank/addImagePortfolio

    
bank/addImagePortfolio ->>

spring-security.xml

this setting will come in picture
<security:intercept-url pattern="/bank/**" access="hasAnyRole('admin','customer')"/>

So you must have either admin or customer role to access the page....
this role will be already present inside spring security when user is already authenticated

Case 1 :
When user is already authenticated
      ->>> Case a (role is valid ) ->> Access the resource 
      ->>> Case b (role is not valid ) ->> 
              Then forward request to 
                access-denied-page="/bank/auth/denied" > this logic URL


Case 3 :
When user is not authenticated
<security:form-login login-page="/bank/auth"
authentication-failure-url="/bank/invalidLogin" 

default-target-url="/bank/homescreen.htm"/>

Then you will be forwarded to
login-page="/bank/auth"  with GET command

       This is the login page




Session Timeout

web.xml

<session-config>
  <session-timeout>10</session-timeout>
 </session-config>


<security:logout 
invalidate-session="true" 
logout-success-url="/bank/auth" 
logout-url="/auth/logout.htm"/>
<security:session-management invalid-session-url="bank/auth/?invalid=true" />


Note : when use is idle for 10 minutes or more and clicks on some links to access the page
then he will fowarded to invalid-session-url="bank/auth/?invalid=true" to show the message

like " Dear user your session has expired , please login again......"