Monday, 11 January 2016

Resetting password of a keycloak user using Rest Service

Not all the time, the users will want to reset the password the in keycloak admin console. Once the keycloak authentication is implemented in an application, there will be scenarios, where password reset has to be done from the third party application. 

Such scenarios can be handled either by keycloak java api or REST services exposed by keycloak.

In this post, let’s see how the password reset of a user in keycloak can be performed by using REST services.
From the code below, keycloak security context can be fetched from the http request.
KeycloakSecurityContext session = (KeycloakSecurityContext)httpreq.getAttribute(KeycloakSecurityContext.class.getName());
String req = “http://localhost:8081/auth/admin/realms/realm_name/users/userId/reset-password";
String jsonBody = "{\"type\":\"password\",\"value\":\"password\",\"temporary\":\"false\"}";
ClientRequest clientRequest = new ClientRequest(req);
clientRequest.body("application/json", jsonBody);
clientRequest.accept("application/json");
clientRequest.header("Authorization", "Bearer " + session.getTokenString());
ClientResponse clientresponse = clientRequest.put(String.class);
String resp = (String) clientresponse.getEntity();

Realm_name          -            Realm name in which the user is created
userId                       -            User id
jsonBody 
security           -           Type of security
value               -           Password to be set for the user
Temporary      -           false (makes sure that user need not change the password after logging into the application)
http://localhost:8081/auth - Keycloak admin console.

Sunday, 10 January 2016

Indexing a file in Elasticsearch using mapper attachment

If you are looking for ways to index a file in Elasticsearch and search through its contents then, this post is for you. Yes, Elasticsearch does allow us to index files of any type (e.g.doc,docx,pdf,ppt,xls). It is basically done using the Apache’s text extraction library Tika. 

The file needs to be encoded as base64 and stored in a field of mapper type “attachment”. The mapping type will not be available by default like String type, so we have to add it using an external plugin.

Below are the steps to index a file.

  Install plugin:

<ElasticsearchDirectory>/bin/plugin install elasticsearch/elasticsearch-mapper-attachments/<version>

The attachment mapper versions for corresponding Elasticsearch version are listed below:

es-1.7
2.7.1
es-1.6
2.6.0
es-1.5
2.5.0
es-1.4
2.4.3
es-1.3
2.3.2
es-1.2
2.2.1
es-1.1
2.0.0
es-1.0
2.0.0
es-0.90
1.9.0

Mapping field type
        curl -XPUT http://localhost:9200/simplyjava/resume -d '{
                " resume":{
                        "properties": {
                        "file":{
                             "type":"attachment"
                        }
          }
 }

Analyzers can also be added to the attachment type.


   Index file in Elasticsearch

    Using Script:

#!/bin/sh
encoded=`cat <filename> | perl -MMIME::Base64 -ne 'print encode_base64($_)'`
resume="{\"file\":\"${encoded}\"}"
echo "$resume" > resume.file
curl -X POST "localhost:9200/simplyjava/resume/user1 " -d @resume.file

   Using Java code:

              File file =new File(<filepath>);
        FileInputStream fis=new FileInputStream(file);
        int length=fis.available();
        byte[]byteArray=new byte[length];
        fis.read(byteArray);
        fis.close();
        BASE64Encoder encoder = new BASE64Encoder();
        base64= encoder.encode(byteArray);
        Map<String, Object> json = new HashMap<String, Object>();
        json.put("file",encodedFile);
       client.prepareIndex("simplyjava", "resume",”user1”).setSource(json).get();

The above script will store the file as an encoded string into the type “resume” under id “user1” with field name as “file”.

Thursday, 7 January 2016

Disabling contents of div element in JSP

This post will explain on how to disable the content of div element in a jsp using jquery, based on the session attribute.

In this example, the checkbox present inside the employeediv is disabled, provided the role of the user fetched from the session is admin.

Fetching the session attribute:

Using this code snippet, the session attribute called ROLE is fetched. Based on the type of role, the “isAdmin” flag is set to either true or false.

<%String sRole = (String)request.getSession().getAttribute("ROLE");
boolean isAdmin = false;
if ((sRole.equals("Admin"))|| (sRole.equals("admin"))|| (sRole.equals("ADMIN")))
            isAdmin = true;
%>

Creating a hidden variable:

The isAdmin flag is stored in a hidden variable.

<INPUT type="hidden" id="role" name="role" value="<%=isAdmin%>"/>     

Disabling the DIV element:

Using the script below, onLoad of jsp, the content of the employeediv is disabled if “isAdmin” is set to true.

<script type="text/javascript">
jQuery(document).ready(function ($) {
  var isAdmin = document.getElementById("role").value;
  if($('#isAdmin')){
            $('#employeediv :input').attr('disabled', true);
    }
});
</script>

All the elements inside the “employeediv” will be disabled if the “isAdmin” is set to true.

<div id="employeediv">
<s:form name="testForm" id="testidForm" action="testaction">
<s:checkbox name="empagreement" id="empchk1" />Employee declaration<br/>
<s:checkbox name="empcitizenship" id="empchk2" />Indian<br/>
</s:form>
</div>

Wednesday, 6 January 2016

Create explicit mappings in Elasticsearch index

An Elasticsearch index can have more than one type. Each type will have its own set of fields. In this post, let’s see how fields can be mapped to various datatypes in Elasticsearch.

Elasticsearch will do its own mapping. Additionally, we can tell it in which way the fields in a document should be stored, indexed and analyzed.

The field that needs to be treated as string or number or geolocation can be specified. The type of analyzer to be used for a particular field and when it should be applied can be defined in field mapping. (Analyzers will be added as settings to an index and it will be applicable for all types. It need not be added for individual document type in Elasticsearch index.)

Field mapping using REST Service:

curl -XPUT http://localhost:9200/simplyjava/user -d '{
"user":{
            "properties": {
                        "name":{
                        "type":"string","search_analyzer":"a1"
                        },
                        "age":{
                        "type":"long"
                        },
                        "dateofbirth":{
                        "type":"date",
                        "format":"yyyy-MM-dd"
                        },
                        "location":{
                        "type": "geo_point"
                        }
            }
}'

Field mapping using Java API:

XContentBuilder mappingBuilder = XContentFactory.jsonBuilder()
                                                                    .startObject().startObject("user")
                                          .startObject("properties")
                                          .startObject("name")
                                            .field("type", "string")
                                            .field("search_analyzer", "a1")
                                          .endObject()
                                          .startObject("age")
                                            .field("type","long")
                                          .endObject()
                                          .startObject("dateofbirth")
                                            .field("type","date")
                                            .field("format","yyyy-MM-dd")
                                          .endObject()
                                          .startObject("location")
                                            .field("type","geo_point")
                                          .endObject()
                                         .endObject()
                                       .endObject()
                                      .endObject();

PutMappingResponse response =client.admin().indices().preparePutMapping("simplyjava").
setType("user").setSource(mappingBuilder).execute().actionGet();


  Note:
 Mappings of indexed document fields cannot be updated. The documents should be deleted and re-indexed in order to get the mapping type changed for the fields in a type.

Sunday, 3 January 2016

Kill tomcat server running on port in windows

If tomcat server is running in eclipse or any other IDE and if the IDE is closed accidentally, without stopping the server running, then next time when we open the IDE and start the server, we will be getting exception related to port number already in use.

            Several ports (8005, 8085, 8009) required by Tomcat7.0.35 are already in use. The server may already be running in another process, or a system process may be using the port. To start this server you will need to stop the other process or change the port number(s).
This is because, the port used by the server is not fred.

Solution
 Open command prompt and type the following commands to kill the process using the port number.

Netstat
               
This command displays the port numbers and network connections that are in use.
 Taskkill

This command kills the processes that are running in the windows machine.

Tuesday, 29 December 2015

Update Index in Elasticsearch

Whenever there is a change to be done in an indexed document, it is not mandatory to replace the entire document, instead elasticsearch allows the partial update of required field in it.
The create index functionality will completely replace the existing details, whereas the update functionality will allow us to partially change the document.

REST Service to update the indexed document:
POST http://localhost:9200/index_name/type_name/document_Id/_update
{
    "doc":{
        "field_name":"new_value"
    }
}

Java API to update the indexed document:

UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index(“index_Name”);
updateRequest.type(“type_Name”);
updateRequest.id(“document_id”);
Map<String, Object> json = new HashMap<String, Object>();
json.put(“field_name”,”field_Value”);
updateRequest.doc(json);
try {
            client.update(updateRequest).get();
} catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
}

Note :  More than one field can be updated using a single method call.


Thanks !! Meet you soon with next post !!

Sunday, 27 December 2015

Delete Index in Elasticsearch

An existing index/type/document in Elasticsearch can be deleted either by using REST service or by using the Java API invocation.
Below are the scripts to delete the index.

Delete complete index :

REST  Service:
$ curl -XDELETE 'http://localhost:9200/<indexname>'

Java API :
client.admin().indices().delete(new DeleteIndexRequest("<indexname>")).actionGet();

Delete a type in index   :

REST Service :
$ curl -XDELETE 'http://localhost:9200/<indexname>/<typename>'

Java API :
client.prepareDelete().setIndex("<indexname>").setType("<typename>").setId("*").execute().actionGet();

Delete a particular document :

REST Service :
$ curl -XDELETE 'http://localhost:9200/<indexname>/<typename>/<documentId>

Java API:
client.prepareDelete().setIndex("<indexname>").setType("<typename>").setId("<documentId>").execute().actionGet();

Note:

The delete operation cannot be rolled back at any point. So make sure to double check the delete command before execution.