Sometime you commit something but then accidentally deleted it and then you would like to bring it back or continue working on it. I had this happened to me and it was frustrating to redo everything I deleted. But then I found out there is a way to recover deleted commit.
Well, you want to reset to that commit so you can continue working on it. Using git reflog, which will show you logs on what you have committed, will show you your deleted commit hash which then you can use to reset to.
git reflog
git reset –hard f52ee7b
June 7, 2019Get list of commits to choose from
git log
Git reset can change the branch pointer to point to any commit in the tree.
git reset --hard <hash>
$ git reset --hard 07a2a46
HEAD is now at 07a2a46 Updated index.html
If you quickly check the log, you will see no history of the commits after 07a2a46
Update branch on remote
git push or git push origin HEAD --force
It is very important to structure your code in a way that is maintainable and easy to work with. A lot of times developers drag their feet to work on a project that is unorganized and hard to follow. Your team members will appreciate the fact that you took the time to organize your code to a certain structure. There are mainly two ways to organize your code. One is by component or layer and the other is by entities.
Component or Layer Driven Layout

Entity Driven Layout

Layout and structure is a matter of preference. When you choose a layout in most cases you will have to stick to that layout and not change. You can mix and match but I don’t recommend this approach as it would make the project very hard to follow.
I usually go with the entity driven layout because it is easier for me to follow my project that way. I can find what I am looking for 99% of the time just by looking at the packages without having to drill down to the classes. Not only that I can really use encapusulation to make that services only access other services on the service layer not on the DAO layer.
June 3, 2019First you need to the spring-boot-starter-security in you pox.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
Configure Spring security using java. This configuration is for APIs.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
@Autowired
private CustomLogoutHandler customLogoutHandler;
@Autowired
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
@Autowired
private CustomAcccessDeniedHandler customAcccessDeniedHandler;
@Bean
public CustomLoginFilter customUsernamePassworAuthenticationFilter() throws Exception {
return new CustomLoginFilter(PathConstantUtil.LOGIN_URL,authenticationManagerBean());
}
@Bean
public CustomAuthenticationFilter customAuthenticationFilter() {
return new CustomAuthenticationFilter();
}
@Bean
public RegistrationBean jwtAuthFilterRegister(CustomAuthenticationFilter customAuthenticationFilter) {
FilterRegistrationBean<CustomAuthenticationFilter> registrationBean = new FilterRegistrationBean<CustomAuthenticationFilter>(
customAuthenticationFilter);
registrationBean.setEnabled(false);
return registrationBean;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// rest call rules
http
.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers(PathConstantUtil.PING_URL).permitAll()
.antMatchers(PathConstantUtil.LOGIN_URL).permitAll()
.antMatchers(PathConstantUtil.SIGNUP_URL).permitAll()
.anyRequest().permitAll();
// logout
http.logout()
.logoutRequestMatcher(new AntPathRequestMatcher(PathConstantUtil.LOGOUT_URL))
.addLogoutHandler(customLogoutHandler)
.logoutSuccessHandler(customLogoutSuccessHandler);
// filter
http.addFilterBefore(customUsernamePassworAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
// stateless
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// handler access denied calls
http.exceptionHandling().accessDeniedHandler(customAcccessDeniedHandler);
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.authenticationProvider(customAuthenticationProvider);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(PathConstantUtil.SIGNUP_URL)
.antMatchers(PathConstantUtil.LOGIN_URL)
.antMatchers(PathConstantUtil.PING_URL)
.antMatchers(PathConstantUtil.AUTH_TOKEN_URL)
.antMatchers(PathConstantUtil.SWAGGER_DOC_URLS)
.antMatchers("/actuator/**");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
methodInvokingFactoryBean.setTargetMethod("setStrategyName");
methodInvokingFactoryBean.setArguments(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
return methodInvokingFactoryBean;
}
}
Here we configure our AuthenticationManager, PasswordEncoder, and web security for http routes.
Configure your Authentication Provider
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserService userService;
/**
* Authenticate user by credentials
*
* @author fkaveinga
* @return Authentication
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
log.info("authenticate(...)");
String email = authentication.getPrincipal().toString();
String password = authentication.getCredentials().toString();
log.info("email: {}", email);
log.info("password: {}", password);
Map<String, String> details = (Map) authentication.getDetails();
log.debug("details: {}", ObjectUtils.toJson(details));
return loginWithPassword(email, password);
}
private Authentication loginWithPassword(String email, String password) {
log.info("loginWithPassword({})", email);
Optional<User> optUser = userService.findByEmail(email);
if (!optUser.isPresent()) {
log.info("user not found");
throw new UsernameNotFoundException("Username or password is invalid");
}
log.info("user found for {}", email);
User user = optUser.get();
log.info("user: {}", ObjectUtils.toJson(user));
if (user.getPassword() == null || !PasswordUtils.verify(password, user.getPassword())) {
log.info("login credentials not matched");
throw new BadCredentialsException("Username or password is invalid");
}
return new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword(), generateAuthorities(user.getRoles()));
}
/**
* Get Authorities for User
*
* @param user
* @return List<GrantedAuthority>
*/
private List<GrantedAuthority> generateAuthorities(Set<Role> roles) {
List<GrantedAuthority> authorities = new ArrayList<>();
if (roles.isEmpty()) {
throw new InsufficientAuthenticationException("No role");
} else {
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getAuthority().toUpperCase()));
}
}
return authorities;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Configure your Login Filter to handle login
public class CustomLoginFilter extends AbstractAuthenticationProcessingFilter {
private Logger log = LoggerFactory.getLogger(this.getClass());
private Map<String,String> authenticationDetails = new HashMap<>();
@Autowired
private UserService userService;
public CustomLoginFilter(String loginUrl, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(loginUrl));
setAuthenticationManager(authManager);
}
/**
* Attemp Authentication process. Pass username and password to authentication provider
* @author fkaveinga
* @return Authentication
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String authorizationHeader = request.getHeader("authorization");
log.info("Login Authorization Header: {}",authorizationHeader);
if(authorizationHeader==null) {
throw new InsufficientAuthenticationException("Authorization Header is null");
}
String email = getUsername(authorizationHeader);
String password = getPassword(authorizationHeader);
log.debug("email: {}",email);
log.debug("password: {}",password);
if(email == null || email.isEmpty()) {
log.info("username is null");
throw new InsufficientAuthenticationException("Username is null");
}
if(password == null || password.isEmpty()) {
log.info("password is null");
throw new InsufficientAuthenticationException("Password is null");
}
authenticationDetails.put("test", "good");
return authenticateWithPassword(email, password);
}
private Authentication authenticateWithPassword(String email, String password) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(email, password);
usernamePasswordAuthenticationToken.setDetails(authenticationDetails);
return getAuthenticationManager().authenticate(usernamePasswordAuthenticationToken);
}
/**
* Write response when request was successful.
* @author fkaveinga
* @return HttpServletResponse
*/
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
log.debug("successfulAuthentication(...)");
String clientIpAddress = HttpUtils.getRequestIP(request);
String clientUserAgent = HttpUtils.getRequestUserAgent(request);
String email = authResult.getPrincipal().toString();
User user = this.userService.getByEmail(email);
JwtPayload jwtpayload = new JwtPayload(user, RandomGeneratorUtils.getUuid());
jwtpayload.setDeviceId(clientUserAgent);
String jwtToken = JwtTokenUtils.generateToken(jwtpayload);
SessionDTO sessionDto = new SessionDTO();
sessionDto.setEmail(email);
sessionDto.setName(user.getName());
sessionDto.setUserUid(user.getUid());
sessionDto.setToken(jwtToken);
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
ObjectUtils.getObjectMapper().writeValue(response.getWriter(),sessionDto);
}
/**
* Write response when request was unsuccessful.
* @author fkaveinga
* @return HttpServletResponse
*/
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
log.debug("unsuccessfulAuthentication(...)");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpStatus.BAD_REQUEST.value());
String message = failed.getLocalizedMessage();
log.debug("Error message: {}",message);
response.setStatus(HttpStatus.BAD_REQUEST.value());
ObjectNode result = ObjectUtils.getObjectNode();
result.put("status", "invalid email or password");
ObjectUtils.getObjectMapper().writeValue(response.getWriter(), result);
}
/**
* Parse token for username
* @param authorizationHeader
* @return String username
*/
private String getUsername(String authorizationHeader) {
log.debug("getUsername(..)");
String username = null;
try {
String usernamePasswordToken = StringUtils.substringAfter(authorizationHeader, " ").trim();
//log.info("usernamePasswordToken: {}",usernamePasswordToken);
String rawToken = this.decodeBase64Token(usernamePasswordToken);
log.debug("rawToken: {}",rawToken);
username = StringUtils.substringBefore(rawToken, ":");
log.debug("username: {}",username);
return username;
} catch (Exception e) {
e.printStackTrace();
}
return username;
}
/**
* Parse token for password
* @param authorizationHeader
* @return String password
*/
private String getPassword(String authorizationHeader) {
log.debug("getPassword(..)");
String password = null;
try {
String usernamePasswordToken = StringUtils.substringAfter(authorizationHeader, " ").trim();
String rawToken = this.decodeBase64Token(usernamePasswordToken);
log.debug("rawToken: {}",rawToken);
password = StringUtils.substringAfter(rawToken, ":");
log.debug("username: {}",password);
return password;
} catch (Exception e) {
e.printStackTrace();
}
return password;
}
/**
* Parse for access token
* @param authorizationHeader
* @return String access token
*/
private String getAccessToken(String authorizationHeader) {
log.debug("getAccessToken(..)");
String bearerToken = null;
try {
bearerToken = StringUtils.substringAfter(authorizationHeader, " ").trim();
log.info("bearerToken: {}",bearerToken);
} catch (Exception e) {
e.printStackTrace();
}
return bearerToken;
}
/**
* Decode authentication token
* @param usernamePasswordToken
* @return String
*/
private String decodeBase64Token(String usernamePasswordToken) {
byte[] decodedBytes = Base64.getDecoder().decode(usernamePasswordToken);
return new String(decodedBytes);
}
}
May 30, 2019
The git stash command is used to stash away your current work and revert back to a clean working directory which matches the HEAD commit.
Let’s say for example that you are in a middle of working on a feature branch and suddenly a customer issue comes up. At this point you want to commit your code but cannot and you want to save it. This is when git stash comes in handy. You can stash your changes and come back to them later after you fix the customer issue.
Note that git stash is stored locally and is not pushed to your git server.
How to stash
Stash your current changes
git stash
Stash your current changes with a message to help you remember
git stash save "message"
You can stash multiple changes in which case they will be in a list.
How to see your stashes
List your stashes
git stash list
See stash summary
git stash show
See stash full diff
git stash show -p
How to apply back your stash(es)
Apply the first stash to your code and remove that first stash from the list
git stash pop
Apply the second stash to your code and remove that second stash from the list
git stash pop stash@{1}
if you want to apply the stash to your code but not remove it from your stash list then use:
git stash apply
How to remove a stash without applying it
Drop the second stash on the list
git stash drop stash@{1}
Remove all your stashes
git stash clear
How to stash partial work
This will iterate through your changes and ask you which file to stash
git stash -p