Wednesday, August 4, 2021

Liferay DXP JNDI Data Source Cofiguration

 This Blog will help us to learn about the JNDI Data Source Configuration in Liferay DXP. We have tested this with Liferay 7.3 with Tomcat.

1. Make Sure JDBC Driver for your data base is available in your Liferay Tomcat Server 😀 without that nothing will work.

2. Declare a JNDI Resource in tomcat/conf/server.xml : Below is sample of the Resource tag and parameters you can customize as per your requirements

<Server port="8005" shutdown="SHUTDOWN">

 

 <GlobalNamingResources>

   <Resource

           name="jdbc/CustomDataSource"

           auth="Container"

           type="javax.sql.DataSource"

           factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

           driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"

           url="jdbc:sqlserver://url:1433;database=mySchema"

           username="mysql"

           password="mysql"

           maxActive="20"

           maxIdle="5"

           maxWait="19999"

   />

 </GlobalNamingResources>


</Server>


3. Declare a ResourceLink in tomcat/conf/context.xml : Below is sample of the Context tag and content.

<Context>

   <WatchedResource>WEB-INF/web.xml</WatchedResource>

   <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>

   <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

   <ResourceLink name="jdbc/CustomDataSource" global="jdbc/CustomDataSource" type="javax.sql.DataSource"/>

</Context>


4. Using JNDI Custom Data Source in your Code.

  • First we need to load the Data Source from the Context, below code will be hepful to load data Source.

private String JNDI_DATASOURCE_NAME = "CustomDataSource"

public void init() {

   try {

//API to load the Context

       InitialContext ctx = new InitialContext();

// Below code will use to get the Data Source from Context

       ds = (DataSource) ctx.lookup(JNDI_DATASOURCE_NAME);

   } catch (Exception e) {

       _log.error("Failed to initialize DataSource, cause: " + e.getMessage());

   }

}

  • Once we have Data Source then we can get the connections.
try {

   Connection connection = ds.getConnection();

}


Hope this Blog is helpfull !


Monday, April 13, 2020

SonarQube Configuration with Liferay DXP

Below are the details which will help to do the setup SonarQube with Liferay DXP.

Required Softwares with Versions :
1. Java 1.8
2. SonarQube 7.8
3. Liferay DXP 
4. Gradle
5. PostgreSQL 12 (You can use any other software if you want)

 I hope all Softwares are available in your system. If not then make it available.

1. PostgreSQL :-

  • Create a new database with the name "sonar".
  • By default, it will create the schema as "public". or else we can create our own schema if we want to use specific schema for sonar.
  • Remember Username and Password which we are using for the 'sonar' database, we can also check in properties of the database if we want to check for Username and Password details.
2. Sonar Qube :-
  • Open sonar.properties from the path 'sonarqube-7.8\conf'
  • Give below properties in that file.
    #----- PostgreSQL 9.3 or greater
    # By default the schema named "public" is used. It can be overridden with the parameter "currentSchema".
    sonar.jdbc.url=jdbc:postgresql://localhost:5432/sonar
    sonar.jdbc.username=postgres
    sonar.jdbc.password=postgres

    Note : sonar is database name and postgres is username and password.

  • Save the details.
  • Start the Sonar Server from the below path "sonarqube-7.8\bin".
  • http://localhost:9000/ to check the Sonar Qube started or not.
  • Once the Sonar Server is up Login into Server by using the default user credentials , admin and admin.
  • Go to my Account -> Security -> Generate Token, save this token or remember as we need to use the Gradle project.
  • You can check the sonar related table in public schema of sonar database.
3. Liferay WorkSpace :-
  • Go to Liferay Workspace folder path
  • Open the file gradle.properties and the below properties
    systemProp.sonar.host.url=http://localhost:9000
    systemProp.sonar.login="abc234"

    Note : abc234 is example token generated from the Sonar Qube , you use the token which you will get from your setup.
  • Open the file "build.gradle", you can use parent project build.gradle file or specific module build.gradle file.
  • I have used parent one, add below properties in that file.

    plugins {  id "org.sonarqube" version "2.7"}

    project(":modules:web") {
        sonarqube {
           properties {
                   property "sonar.inclusions", "**/src/main/java**"
            }
         }
    }

    Note: For more details, you can refer "https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/"
  • Save the Files
4. Execution :

  • Open the Liferay Workspace path in command prompt.
  • Run the command "gradlew sonarQube".
  • It will take some to for execution.
  • Once you see "Build Successfull".
  • You can see the project result in Sonar Server in the path "http://localhost:9000/projects" with the Liferay Workspace name.
  • Below is the example screenshot for your reference.
Note : Please don't go with my error report 😉

Friday, April 10, 2020

Checking Permission for Page in Liferay

The below code will help you to check the guest permission for page in Liferay.

import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.Role;
import com.liferay.portal.kernel.model.ResourcePermission;
import com.liferay.portal.kernel.service.ResourcePermissionLocalServiceUtil;
import com.liferay.portal.kernel.service.RoleLocalServiceUtil;
import com.liferay.portal.kernel.util.Validator;

// We are passing the Layout Object, as we know in liferay page information will be available in Layout table
public static boolean checkguestpermission(Layout layout) {
boolean guestPermission = false;
try {
Role guestRole =  RoleLocalServiceUtil.fetchRole(layout.getCompanyId(), "Guest");
List resourcePermissionList = ResourcePermissionLocalServiceUtil.getResourceResourcePermissions(layout.getCompanyId(),
layout.getGroupId(), Layout.class.getName(), String.valueOf(layout.getPlid()));
logger.debug("resourcePermissionList :" + resourcePermissionList.size());
for(ResourcePermission permission : resourcePermissionList){
                  // ActionId 1 for VIEW permission in liferay
if(permission.getActionIds() == 1){
Role role = RoleLocalServiceUtil.getRole(permission.getRoleId());
if(Validator.isNotNull(role)&&permission.getRoleId()==guestRole.getRoleId()){
guestPermission = true;
}
}
}
}catch (PortalException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return guestPermission;
}

Wednesday, March 11, 2020

Push JSON Data / File to AWS S3 Bucket from Liferay by presinged URL

//The below code will help you to send the JSON data/File to AWS S3 Bucket from Liferay Portlet.

package com.portlet;

import com.constants.TestPortletKeys;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
import com.liferay.portal.kernel.util.StringPool;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.portlet.Portlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.osgi.service.component.annotations.Component;

/**
 * @author Inthiyaz
 */

@Component(immediate = true, property = { "com.liferay.portlet.display-category=category.sample",
"com.liferay.portlet.instanceable=true", "javax.portlet.init-param.template-path=/",
"javax.portlet.init-param.view-template=/view.jsp", "javax.portlet.name=" + TestPortletKeys.Test,
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=power-user,user" }, service = Portlet.class)

public class TestPortlet extends MVCPortlet {

@Override
public void render(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
// TODO Auto-generated method stub
System.out.println("Render Method of a Test Portlet");
try {
// Creating sample JSON Data
JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
for (Layout layout : LayoutLocalServiceUtil.getLayouts(-1, -1)) {
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
jsonObject.put("id", layout.getPlid());
jsonObject.put("title", layout.getName());
jsonArray.put(jsonObject);
}
System.out.println("JSON :" + jsonArray);
JSONObject jsonData = JSONFactoryUtil.createJSONObject();
// Client Id of AWS S3 bucket
jsonData.put("client_id", "1123231daasdfasdfsdf");
// Client Secret Key of AWS S3
jsonData.put("client_secret", "111111111111112222222222asdfdsf22223333333wsdfadsfawewrwerwerqwer");
//Give sample scope if you have any
jsonData.put("scope", "some_sample_scope");
//calling method to generate connection from AWS and pass jSON data
connectionGenerator(jsonData.toString(), jsonArray);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.render(renderRequest, renderResponse);
}

// Method to create connection and generate the token
public static void connectionGenerator(String jsonData, JSONArray jsonArray) throws IOException {
HttpClient client = HttpClients.createDefault();
//Provide AWS  Authorize URL
String url = "http://123adfasdfasdexecute-api.com/v1/authorize";
StringEntity entity = new StringEntity(jsonData);
HttpPost httpPost = new HttpPost(url);
               httpPost.setEntity(entity);
               httpPost.setHeader("Accept", "application/json");
               httpPost.setHeader("Content-type", "application/json");
String signedUrl = StringPool.BLANK;
try {
System.out.println("HTTPPSOT :-" + httpPost);
HttpResponse response = client.execute(httpPost);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String responseJSON = EntityUtils.toString(response.getEntity());
JSONObject jsonObj = JSONFactoryUtil.createJSONObject(responseJSON);
String tokenObj = jsonObj.getString("payload").toString();
JSONObject token = JSONFactoryUtil.createJSONObject(tokenObj);
System.out.println("Token Object :" + tokenObj);
// Passing generated token and input JSON Array data
generatSignedURLfromPayload(token.get("token").toString(), jsonArray);
} else {
System.out.println( "Http Status is not Okay while generating token :" + response.getStatusLine().getStatusCode());
}
} catch (JSONException e) {
System.out.println("Exception in Client while generating token");
}
}

// Method to generate Signed URL from Payload by using a token
private static void generatSignedURLfromPayload(String token, JSONArray jsonArray) throws ClientProtocolException, IOException {
System.out.println("Getting Singed URL");
HttpClient client = HttpClients.createDefault();
// AWS S3 URL where we need to push the file with JSON DATA
String url = "http://123adfasdfasdexecute-api.com/v1/entity/upload-url?name=processdata";
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Authorization", token);
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("Content-type", "application/json");
String signedUrl = StringPool.BLANK;
try {
HttpResponse response = client.execute(httpGet);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String responseJSON = EntityUtils.toString(response.getEntity());
JSONObject jsonObj = JSONFactoryUtil.createJSONObject(responseJSON);
JSONObject payLoad = JSONFactoryUtil.createJSONObject(jsonObj.getString("payload"));
signedUrl = payLoad.getString("url");
// By using Pay Load URL pusing jsondata
uploadFileContenttoAWSS3(signedUrl, jsonArray);
} else {
System.out.println("Http Status is not Okay while Signed URL :" + response.getStatusLine().getStatusCode());
}
} catch (JSONException e) {
System.out.println("Exception in Client in signed URL");
}
}
//Method to upload json data to AWS S3
public static void uploadFileContenttoAWSS3(String api, JSONArray jsonArray)
throws ClientProtocolException, IOException {
System.out.println(" Upload data to AWS S3");
URL url = new URL(api);
//used to form a connection
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-type", "plain/text");
//Used to write the data after connection
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(jsonArray.toString());
out.close();
connection.getResponseCode();
System.out.println("HTTP response code: " + connection.getResponseCode());
}
}

Friday, March 6, 2020

Checking Category of a Page in Liferay

import com.liferay.asset.kernel.model.AssetCategory;
import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.service.AssetCategoryLocalServiceUtil;
import com.liferay.asset.kernel.service.AssetEntryLocalServiceUtil;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
import com.liferay.portal.kernel.util.LocaleUtil;

AssetEntry assetentry = null;
List<AssetCategory> categoryList = null;
Locale loc = LocaleUtil.ENGLISH;
//Using a dynamic query to fetch all the categories with the name "Not_Valid_Page"
DynamicQuery query = DynamicQueryFactoryUtil.forClass(AssetCategory.class).add(PropertyFactoryUtil.forName("name").eq("Not_Valid_Page"));
categoryList = AssetCategoryLocalServiceUtil.dynamicQuery(query, 0,1);

for(AssetCategory assetCategory:categoryList) {
    // It will Fetch the Category with name "Not_Valid_Page"
    System.out.println(" Category Name"+assetCategory.getName());
}

//Fetching all the Layouts
for(Layout layout:LayoutLocalServiceUtil.getLayouts(-1, -1)) {

assetentry = AssetEntryLocalServiceUtil.getEntry(Layout.class.getName(),layout.getPrimaryKey());
long assetCategoryId[] = assetentry.getCategoryIds();
List<AssetCategory> assetCategories = assetentry.getCategories();

if(assetCategories.contains(categoryList.get(0))){

//layout contains the detail of the page which contains the category of "Not_Valid_Page"

}
}

Tuesday, October 15, 2019

Liferay DXP Patching Tool

This Blog will help you to apply the Liferay Patch to Liferay Enterprise users. As we know that Liferay provides patching-tool utility to update the latest fix pack. Liferay Enterprise users by default they will have a Patching tool in the server. If it is not available then we can download from the Liferay Website. 
  1.  Download and Configure Patching Tool.
  • Download patching from Liferay Website.
  • Below is the folder structure inside the patching tool 
  • Change the below details in default.properties files.
            patching.mode=binary
               war.path=../tomcat-8.0.32/webapps/ROOT/
                 global.lib.path=../tomcat-8.0.32/lib/ext/
                    liferay.home=../
        • Inside the patches folder we need to copy the Patch file zip. Below i have two versions copied into my local pathches folder below is the screenshot.
        • After copying the Patching file Open the patching tool (liferay-dxp-digital-enterprise-7.0-sp6\patching-tool\) path in command prompt. 
        • In the above path, we have the files "patching-tool.bat" - for windows system and "patching-tool.sh"- for Linux or ubuntu system.
        • Below are the few commands which are available.
                   patching-tool info - This command is used to display the information about the patch available in your Liferay server and the version of the patching tool.
                     patching-tool auto-discovery - This command is used to auto-discover the Liferay Server based on your default.properties file.
                       patching-tool setup - This command is used to setup the patching.
                       patching-tool install- This command is used to install the patching.
            • First run "patching-tool setup" or   "./patching-tool.sh setup" for the setup of patch.
            • Then run "patching-tool install" or   "./patching-tool.sh install" to install the patch.
            • After installing the patch we can check the version of the patch by using the "patching-tool info" command.

            Thursday, August 8, 2019

            Retrieve field Value from Custom Document Type of Liferay

            The below code helps you to get the field values from the custom document type of Liferay.

            import com.liferay.portlet.documentlibrary.model.DLFileEntry;
            import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
            import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
            import com.liferay.portlet.documentlibrary.model.DLFileVersion;
            import com.liferay.portlet.documentlibrary.model.DLFolder;
            import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
            import com.liferay.portlet.documentlibrary.model.DLFileEntry;
            import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
            import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
            import com.liferay.portlet.documentlibrary.model.DLFileVersion;
            import com.liferay.portlet.documentlibrary.model.DLFolder;
            import com.liferay.portlet.documentlibrary.model.DLFolderConstants;

                public static String getFieldValue(DLFileEntry fileEntry,String name){
                String feildValue = StringPool.BLANK;
                try {
                 DLFileEntryType dlFileEntryType = DLFileEntryTypeLocalServiceUtil.getFileEntryType(fileEntry.getFileEntryTypeId());
                 List ddmStructures = dlFileEntryType.getDDMStructures();
                 if(Validator.isNotNull(ddmStructures)){
              DDMStructure ddmStructure = ddmStructures.get(0);
                 
                   DLFileVersion dlFileVersion = fileEntry.getFileVersion();
                   DLFileEntryMetadata dlFileEntryMetadata = DLFileEntryMetadataLocalServiceUtil.getFileEntryMetadata(ddmStructure.getStructureId(), dlFileVersion.getFileVersionId());
                 
                   Fields fields = StorageEngineUtil.getFields(dlFileEntryMetadata.getDDMStorageId());
                   if(Validator.isNotNull(fields.get(name))){
                    feildValue= GetterUtil.getString(fields.get(name).getValue());
                   }
                 }
                } catch (PortalException | SystemException e) {
              _log.error(e.getMessage(), e);
                }
                return feildValue;
                }



            Liferay DXP JNDI Data Source Cofiguration

             This Blog will help us to learn about the JNDI Data Source Configuration in Liferay DXP. We have tested this with Liferay 7.3 with Tomcat. ...