Wednesday, October 25, 2017

hashCode and equals, why they are needed in Java?

All object in java are inherited from Object class, this Object has two methods hashCode() and equals(Object obj). We normally do not care about why these are made and what is the significance of these methods to derived objects.

To begin with, if we have Java objects and wanted to compare those object whether they are same or not. Primitive type values can be directly compared for equality with == operator. What if we use the same operator to check equality to Java object, then we are messed up. That is because the == operator compares the reference values of the objects. That means if two objects reference to the same memory address, they are equal. To clearify this, lets take example:

int a=10;
int b=10;

a==b  //true

Integer a=new Integer(10);
Integer b=new Integer(10);

a==b //false

First example give true because we are comparing values and they are same. In case example, they are object and the references of the objects are compared, although the values are same, they are NOT equal!!!


In many problem scenario, we need some mechanism so that the objects are evaluated based on their properties. In the above example, the evaluation of a and b should give the same result because they represent same, although they are different objects. For that we need to use equals() method of Object.


public boolean equals(Object object)

So, we override and implement this method to our object so that we can evaluate objects for equality based on their contents. So, two objects are evaluated as equal if this method return true.  

public native int hashCode()

When we override equals method, we MUST override hashCode method also. Why?

[Because a violation of the general contract for Object.hashCode will occur, which can have unexpected repercussions when your class is in conjunction with all hash-based collections.]

So, the rule is if equals() returns true, then their hashCode should ALWAYS be equal. But the other way might not be true. That is, if equals() returns false, it is not necessary that the two objects have different hashCodes.


How to create hash code?


How to implement equals method?



Wednesday, September 27, 2017

Enabling SSL in Tomcat


To install and start tomcat server is a really straight forward, but to run it securely needs some extra configuration. In this article I am going to describe the steps needed to enable encryption in tomcat server so that the communication between client and server is being carried by encrypting the data traffic, and nobody in between client and server can read the information.

Creation of KeyStore

The first and foremost requirement to implement SSL is creation of keystore file. The documentation says only three formats are supported  (JKS, PKCS11 or PKCS12) and I am gonna use JKS format because it is java standard keystore and can be created using keytool commands that comes with Java installation. 

So, lets create keystore. Just execute the command, it creates a jks file with private key and certificate. 

keytool -genkey -alias tomcat -keyalg RSA -keystore tomcat.jks -storepass ***** -validity 3650

Please the not keystore password used while creation. This is needed in tomcat configuration. Yes, tomcat.jks should be placed in a very secured location in the server. 


Configuration

After creation of keystore file, the next step is to copy this file to the server. It is best practice to copy it in conf folder of tomcat installation directory. 

So, we go to tomcat installation directory. In conf folder there, we open server.xml file where can enable SSL and provide the keystore file location along with keystore password. 


So, basically, we add the following connector element in  service element:
<Service name="Catalina">
.
.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
        maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="conf/tomcat.jks" keystorePass="****" /> 
.
.
.
</Service>


Limiting SSL Usage

Obviously, we want to disable plain text communication after enabling SSL. So far we have configured, supports bot encrypted and plain communication. So, we disable plain text communication. 

Now, we add the following lines at the end of the file inside tags. 

   
    <security-constraint>
    <web-resource-collection>
        <web-resource-name>secure-tomcat-app</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

   


Restart Tomcat server and now the connection to the tomcat server is always secure. 



Monday, September 18, 2017

Ubuntu Basics

In this article, I am going to write some basic Ubuntu operations which we need day to day. I am gonna describe everything as a list and this list goes on updated.

Font Installation

One of the frequently facing problem we get is the required fonts are not installed and we have to install by ourselves. Yes, there are several ways to install fonts in Ubuntu system. First of all, we have to know where the fonts are located and what is the purpose of the fonts.

First of all, we have to know about user defined fonts i.e. every every defines their fonts in their home directory:

~/.fonts

The fonts in this directory are only for the specific user and not available globally.

If we have to make the fonts globally available, then we have to copy the fonts into other locations.The locations can be defined in

/etc/fonts/fonts.conf 

The default directories are
/usr/share/fonts, 
/usr/local/share/fonts 
and
~/.fonts

So, if we copy directly into the /usr/share/fonts or /usr/local/share/fonts to make the font available for all users. Of course, you have to be administrator to copy the fonts into the above-mentioned directories.

Here is the sample fonts to test. 

Sample Fonts


After copying into the corresponding directories, we have to run the following commands:

sudo fc-cache -fv

If system is rebooted, we do not need to execute above command, fonts are loaded automatically.

After installation is complete, we check if the fonts have been successfully installed.

sudo fc-list |grep verdana

If the font is successfully installed, then it show the newly installed font.

Note: we need to restart the application which are using the font to reflect the newly installed fonts.

Localization

This is one of the common problems I have faced. Basically, when using the German alphabets with umlauts, they are not properly displayed because of unicode related problems.

Here, I will try to explain as simple as possible to work around with that:

  • Check the current local settings:
      $ locale

  • See the available locales
      $ locale -a  

  • If locale is not in the list, then it should be generated(installed)
     $ locale-gen fr_FR.UTF-8


  • To regenarate locales, 
     $ locale-gen  
  • The default settings are stored in /etc/default/locale file. 
      We can directly change the contents of this file. Or we can use the command update-locale.
      $ update-locale LANG=de_DE.UTF-8

Note: the supported locales are located in the file /usr/share/i18n/SUPPORTED.

Shorcut Method:  

From terminal, run the following command, and select the required locales. That does everything we needed!

$ sudo dpkg-reconfigure locales


Yes, it is recommended to restart the system to properly load the locales.

Quickly Test USB Boot

  • Install qumu

            sudo apt install qemu

  • Test ISO
      qemu-system-x86_64 -cdrom filename.iso
  • Test USB
      qemu-system-x86_64 -hda /dev/sdx



Date Time Settings


This section describe how can we set date and time in Ubuntu system from command terminal. The auto update of date time is carried out through NTP server, the configuration of datetime sync server is a different topic. We simply set the date and time here.

First of all, there are two clocks: 1) System clock, 2) Hardware clock

Here, the date time set in hardware clock is what we see the time in Bios, and if Bios time is not correct, then the system time could be also incorrect because when system boots, it gets time from Hardware clock.

So, if hardware clock is wrong by any chance, the system time also gets wrong.

1) See system date and time
$ date
2) Set system date and time
$ sudo date -s '2017-10-04 16:31:32'
3) See hardware clock time
$ sudo hwclock
4) Set hardware clock time from system time
$sudo hwclock -w
5) Set system time from hardware clock time
$sudo hwclock -s

In the above commands, -w can be replaced with --systohc and -s can be replaced with --hctosys.

Enable Remote Desktop in Ubuntu Server  

If we install standalone Ubuntu server, and want it to be accessible via remote desktop, we have to do some extra task. Since, ubuntu-server comes without any desktop application, i.e. no GUI possible, only terminal. Thats cool if you are familiar with command line terminal. If you still want to make your server available via remote desktop, we have to install the desktop application in the server. The program we need for remote desktop is xrdp.

So, we install it using terminal as follows:

sudo apt update
sudo apt upgrade
sudo apt install xrdp
sudo apt install ubuntu-mate-core ubuntu-mate-desktop 
echo mate-session >~/.xsession
sudo service xrdp restart


Then we are ready to connect using rdesktop from Linux and remote desktop from windows based systems.





Saturday, August 19, 2017

More on Software Testing

In this article, I am going to write more about software testing. The quality control of a software product is carried out in different software testing methodologies. The software testing is a phase that should not be neglected, because if a defect is found at the time of software delivery, the cost will be increased by 10 times, and will be 20 times more at the maintenance phase. So, it is recommended to carry out testing when the software development begins.

Software Phases

There are 5 main phases of software development:

1) Documentation: Requirement analysis, design document, test documents
2) Coding/Execution: The development phase
3) Testing: Different testing methodologies
4) Deployment : The software is delivered to the customer
5) Maintenance: After deployment, if any failure is detected.

Software Testing

The software testing can be broadly categorized into two categories:

A. Blackbox Testing: Tested overall functionalities of the software without knowing the details of the implementation, or design.
B. Whitebox Testing: White box testing also considers the implementation details, software design, database design.


Defect & Failure: If a defect reached to end-user, it is failure. 60% defects are prone to exist in design phase and 40% defects in development phase.

Testing Process

The testing process

Unit Testing => Integration Testing => System Testing => Acceptance Testing

Acceptance testing is carried out alpha-testing(carried out in development site) and beta-testing(tested by actual customer).


When a bug is found or some module is changed/added, we have to carry out
1) Confirmation Testing: Confirm that the bug/defect is fixed.
2) Regression Testing: Testing if all other parts of software( or module) are working

More...

We must be also concerned with

1) Defect cascading: A defect can be propagated to other modules and affects those modules too, this is called cascading.
2) Cohabiting Software: When software is installed in actual end-user machine, there might be other software installed which using the same shared libraries or resources. In this scenario, the other software need to be carried out testing.







Monday, July 31, 2017

Create a Reactjs Application

Upgrade Nodejs

The default installed version of Nodjs in Ubuntu 16.04 is 4.x and I could not upgrade it to the latest 6.x from normal update using apt update. So, we need to add sources for nodejs to upgrade to the latest version. We need latest version which functions better and the create-react-app works perfectly.

So, to upgrade, we need to create a new sources list file for nodejs.

  1. Create a new file /etc/apt/sources.list.d/nodesource.list with the following contents: deb https://deb.nodesource.com/node_6.x xenial main
    deb-src https://deb.nodesource.com/node_6.x xenial main
  2. Add public key which is needed:
    curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
  3. Update Repository
    sudo apt update
  4. Check
    sudo apt-cache policy nodejs
    You will see which version gonna install
  5. Install
    sudo apt install nodejs   

Alternative for the above mentioned method will be NVM (Node Version Manager). The installation of nvm is carried out as follows:


1) cd /tmp
2) wget https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh
3) chmod +x install.sh
4) sudo bash install.sh
5) Restart terminal
6) Now, you can check the available versions:
   nvm ls-remote
7) Finally, install the version wanted (I prefer LTS one!)
    sudo nvm install v6.11.2

[
In case, if nvm ls-remote returns N/A message, you have to insert the following tow lines as the environmental variables.

export NVM_NODEJS_ORG_MIRROR=http://nodejs.org/dist
export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

So far so good, if multiple versions are installed, then we have to select the one as default using
(*Lists the versions installed *)
nvm ls  
(*Select the one as default*)
use [Version]

]
Create Reactjs Project

After installation of nodejs, now we create a reactjs application. The easiest method is install create-react-app package and start with a new scratch project.

npm install -g create-react-project
create-react-app my-app
cd my-app
npm start

Thats it! Now you can see the running react application in localhost:8000

After the application is ready for deployment, we use the following command to build.

npm run build

This process creates a build directory with all files we need to deploy.

Sunday, June 18, 2017

Make your own git push repository

Git, the most popular source control system, is one of the important concept every programmer should know nowadays. In my initial career, I stated used Visual Source Safe, now it is outdated, later, I started using subversion, and currently I am learning git which sounds very promising and powerful for me. In this article, I am going to write something about your own git push server configuration so that you do not need the public git server anymore(also you can store you private projects which you do not like to make your source code publicly visible). Another advantage is automation, if you have dedicated git server and then running build service (Jenkins, e.g.), then we can automate the task of deployment using build automation tool.

But I wont explore everything here, I would only explore how can you create a push server, create a new project and commit and push this project to this newly created git push server. Normally, there are two server, one server to commit, which is located in the same machine. So, basically, all source control related operations are carried out from this local git server(commit, differences etc). So a local git server can perform all tasks a subversion server do, the only difference is the subversion server can be located externally. Now, git provides the facility of pushing the project which means, the tasks you have done so far is complete and wanted other users to get your changes. 

So far we became familiar with some theoretical background, which is necessary. Now, I am gonna start how we can carry out the processes to prepare a git server(local) and git push server(remote).

REMOTE SERVER

1) Prerequisites

The first and foremost thing to think before begin is the server which should be running and accessible from your development computer.  I prefer Ubuntu-Server which makes the tasks easy as compared to windows.

If git is not installed, please install it. 

sudo apt install git-core

2) Create user git

sudo useradd git

Create password for git:

passwd git


[Alternative way is to create user certificates so that user can directly connect to the git server without even needing passwords]

3) Create folder to store project repositories

Now, I define a folder where I want all git based projects. For that, I have created a folder /opt/git where all project repositories are stored.

su git
mkdir /opt/git


Important: change the owner of /opt/git to git, if this folder was created by other users.

sudo chown -R git:git /opt/git

4) Create repository
su git
cd /opt/git
sudo mkdir project.git
cd project.git
git init --bare


So far, we have created an empty repository where we can push our changes from our development computers.

Please not that, the location of this git repository is represented by:

git@server:/opt/git/project.git

So other users can simply clone this project using

clone git@server:/opt/git/project.git



LOCAL REPOSITORY

For any git project, git prepares local repository where it stores project commits. We can even compare changes, restore to previous versions. Everything we can do even without needing remote server. A developer can manage all changes locally even without letting other developers notice. The remote push server mentioned above is need to push your changes when everything from your side is ready and other developers can implement it.

This section focuses on how can we prepare git client so that we can go on developing.

1) Simple Method:

This is simple method:

cd /home/krishna/workspace
git clone git@server:/opt/git/project.git

It creates an empty project with git repositories prepared. Now we can carry out any changes in this project(create a new file), we can commit it, and then push it to our own server prepared above.

2) Lengthy Method:

This method is a bit lengthy, in case some people interested, they are free to do. We create the repository by ourselves and add remote server to push.

cd /home/krishna/workspace/project
git init
git add .
git commit -m "first commit" .

So far so good, everything is done locally. 

Now we define the remote server

git remote add origin git@server:/opt/git/project.git
git push origin master 


More Tasks:

1) Disable git to access remote  shell

We have a new git user created, and this users can also login to shells to access the remote computer which is undesirable. So, we now enable git use only push and pull using ssh connection which is obtained for enabling git-shell to the git user.
a) Add git-shell in /etc/shells
cat /etc/shells
If git-shell does not exist here, we have to insert git-shell location here
which git-shell
copy this location to the end of /etc/shells. The file should look something like this:

/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
/usr/bin/git-shell

Now we enable only git-shell for git user :

sudo chsh git -s $(which git-shell)

Here chsh means change shell. 

That's it, now we can not be able to login to remote server using ssh as git user.

2) Enable password-less login for git users

It is not always appropriate to provide password to authenticate to git remote server, so we create certificates for users and the specified user can login without need of passwords.


Now lets create a private and a public key for myself.

















Tuesday, June 6, 2017

Users Management in Cassandra

In my previous article, I have introduced on how can we begin with installation and configuration, and this article more focused on further Cassandra management. I will also share my experiences regarding this.

Change Password of Super User

This article mainly focuses on users management. In previous chapter I have discussed up-to network connection, we just used the command

cqlsh [SERVER-ADDRESS]

Magically it got connected, I did not have any idea regarding users. Because of security, database comes with users with different roles and the defined user only has access the database. It was my fault that I could notice that at first, actually cassandra comes with default super user cassadra with password cassandra. The first step is to change the cassandra password as soon as possible.

root user: cassandra
default password:cassandra

So, first begin with changing password. I tried login without password, and executed the following command:

cqlsh [SERVER-ADDRESS]
alter user cassandra with password '**********';

I got error  saying "..CassandraRoleManager does not support PASSWORD", initially that sound weird, but later I noticed that we have to further modify configuration in conf/cassandra.yaml file.

Find the line with authenticator, and modify it to

authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer

Restart cassandra service to activate these configurations, now we need user name and password to connect to database. And, good news, is we can now alter password of default superuser (cassandra).

alter user cassandra with password '*****************';

Create Custom User

We have to first note that, there are two types of users in cassandra, supseruser and nonsuperuser. The difference is clear, superuser has some elevated roles compared to nonsuperuser. Superusers can create new users, delete users, change passwords of users, while normal users can only change their own password.

So, to create a custom user you have to be a superuser. First we login with superuser:

csqlsh [SERVER-ADDRESS] -u cassandra

Provide password for cassandra. Then, after successful login,  we provide the following command:

create user if not exists frietec with password '********' supseruser;

Thats it! Now, we created users and defined roles to access.