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"

}
}

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. ...