Useful groovy scripts for SAP hybris Commerce. Part 1
The Groovy console is a very handy tool to develop and run scripts inside hybris without touching the source code. It is a very powerful tool for debugging purposes, especially if you need to troubleshoot the remote system. In this article, I collected some of the scripts I use regularly in my work.
This is a PART 1 of the series. Today I share the following Groovy scripts:
Keep in mind that you will be able to see only the local logs. In the well-configured cluster environment, the storefront logs are not available from the host where hac is accessible.
Due to the tab-delimited, the output can be easily copied to Excel via copy-paste (Chrome->Notepad, Notepad->Excel).
If you need to process some specific fields differently (for example, extract the data from the model), you can collect field names and add the custom code inside the second loop. In the next example, I also demonstrate how to use modelService for resolving PKs.
*The code above may not work with some configurations.
*The screenshot above shows only composed types for the sake of simplicity.
There are three columns: path, object and count. The count shows how many objects of the type is in the database. The script displays the tab-separated data. In order to get the table as shown above, copy the text to Notepad first (to get rid of formatting) and then from Notepad to Excel spreadsheet.
- Display any file on the server
- Execute a command
- Show last N lines from the console log
- Execute a flexible search query
- Execute a raw SQL query
- Retrieve an item by PK
- Modifying objects
- Removing items
- Sending data by e-mail
- Importing IMPEX
- Print all properties of an object
- Print all methods of an object
- Print the hybris type tree
- Print hybris type stats
Display any file on the server
It may help you if you have no access to the environment (besides /hac), but you need to get some info from the local file system.Execute a command
println "ls -la".execute().text
Show last N lines from the console log
println "tail -n 50 ../../../../log/tomcat/console.log".execute().text
Execute a Flexible Search query
flexibleSearchService = spring.getBean("flexibleSearchService");
query = "select {pk} from {Category}";
result = flexibleSearchService.search(query);
itempk = "";
for (item in result.getResult()) {
println item.getName();
}
query = "select {pk} from {Category}";
result = flexibleSearchService.search(query);
itempk = "";
for (item in result.getResult()) {
println item.getName();
}
Retrieve an item by PK
import de.hybris.platform.core.PK;
Long examplePK = ...;
object = modelService.get(new PK(examplePK));
print object.getPk();
print ", ";
println object.getName();
Long examplePK = ...;
object = modelService.get(new PK(examplePK));
print object.getPk();
print ", ";
println object.getName();
Execute a raw SQL query
The following code may not work with some hybris versions because of the HAC classes are not available from Groovy.import de.hybris.platform.hac.data.dto.SqlSearchResultData;
import de.hybris.platform.hac.facade.impl.DefaultFlexibleSearchFacade;
SqlSearchResultData searchResult;
query =
"select createdTS, modifiedTS, PK, p_uid, p_name, p_catalogVersion, p_visible from cmscomponent limit 0,10";
;
flexibleSearchFacade = new DefaultFlexibleSearchFacade();
result = flexibleSearchFacade.executeRawSql(query, 2000000, false);
println result.getHeaders().join("\t");
for (item in result.getResultList()) {
println (item.join("\t"));
}
import de.hybris.platform.hac.facade.impl.DefaultFlexibleSearchFacade;
SqlSearchResultData searchResult;
query =
"select createdTS, modifiedTS, PK, p_uid, p_name, p_catalogVersion, p_visible from cmscomponent limit 0,10";
;
flexibleSearchFacade = new DefaultFlexibleSearchFacade();
result = flexibleSearchFacade.executeRawSql(query, 2000000, false);
println result.getHeaders().join("\t");
for (item in result.getResultList()) {
println (item.join("\t"));
}
import de.hybris.platform.hac.data.dto.SqlSearchResultData;
import de.hybris.platform.hac.facade.impl.DefaultFlexibleSearchFacade;
import de.hybris.platform.core.PK;
SqlSearchResultData searchResult;
query =
"select * from users limit 0,2";
;
flexibleSearchFacade = new DefaultFlexibleSearchFacade();
result = flexibleSearchFacade.executeRawSql(query, 2000000, false);
modelService = spring.getBean("modelService");
for (item in result.getResultList()) {
columnsCounter=0;
for (fieldValue in item) {
fieldName = result.getHeaders()[columnsCounter++];
if (fieldName == "PK") {
print modelService.get(new PK(fieldValue as Long)).getName() + "\t";
if (fieldName == "TypePkString") {
print modelService.get(new PK(fieldValue as Long)).getName() + "\t";
}
}
println "";
}
import de.hybris.platform.hac.facade.impl.DefaultFlexibleSearchFacade;
import de.hybris.platform.core.PK;
SqlSearchResultData searchResult;
query =
"select * from users limit 0,2";
;
flexibleSearchFacade = new DefaultFlexibleSearchFacade();
result = flexibleSearchFacade.executeRawSql(query, 2000000, false);
modelService = spring.getBean("modelService");
for (item in result.getResultList()) {
columnsCounter=0;
for (fieldValue in item) {
fieldName = result.getHeaders()[columnsCounter++];
if (fieldName == "PK") {
print modelService.get(new PK(fieldValue as Long)).getName() + "\t";
if (fieldName == "TypePkString") {
print modelService.get(new PK(fieldValue as Long)).getName() + "\t";
}
}
println "";
}
Modifying objects
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery;
flexibleSearchService = spring.getBean("flexibleSearchService")
mimeService = spring.getBean("mimeService")
modelService = spring.getBean("modelService")
def findMediasWithoutMime() {
query = "SELECT {PK} FROM {Media} WHERE {mime} IS NULL")
flexibleSearchService.search(query).result;
}
findMediasWithoutMime().each {
it.mime = mimeService.getMimeFromFileExtension(it.realfilename)
modelService.save(it)
}
flexibleSearchService = spring.getBean("flexibleSearchService")
mimeService = spring.getBean("mimeService")
modelService = spring.getBean("modelService")
def findMediasWithoutMime() {
query = "SELECT {PK} FROM {Media} WHERE {mime} IS NULL")
flexibleSearchService.search(query).result;
}
findMediasWithoutMime().each {
it.mime = mimeService.getMimeFromFileExtension(it.realfilename)
modelService.save(it)
}
Removing items
flexibleSearchService.search("select {pk} from {product} where ....").result.each {
modelService.remove(it)
}
modelService.remove(it)
}
Sending data by e-mail
// Create a temporary file for the demo
file = File.createTempFile("stuff",".tmp")
file.deleteOnExit()
pw = new PrintWriter(file)
pw.println 'This is line 1'
pw.println 'This is line 2'
pw.close()
// Create the email
email = de.hybris.platform.util.mail.MailUtils.getPreConfiguredEmail()
email.addTo('r.aliev@gmail.com')
email.subject = 'Important stuff attached'
email.msg = 'Here is your attachment'
// Create an attachment that is our temporary file
attachment = new org.apache.commons.mail.EmailAttachment();
attachment.path = file.absolutePath
attachment.disposition = org.apache.commons.mail.EmailAttachment.ATTACHMENT
attachment.description = 'Stuff'
attachment.name = 'stuff.txt'
// Attach the attachment
email.attach(attachment)
// Send the email
email.send()
// Clean up
file.delete()
file = File.createTempFile("stuff",".tmp")
file.deleteOnExit()
pw = new PrintWriter(file)
pw.println 'This is line 1'
pw.println 'This is line 2'
pw.close()
// Create the email
email = de.hybris.platform.util.mail.MailUtils.getPreConfiguredEmail()
email.addTo('r.aliev@gmail.com')
email.subject = 'Important stuff attached'
email.msg = 'Here is your attachment'
// Create an attachment that is our temporary file
attachment = new org.apache.commons.mail.EmailAttachment();
attachment.path = file.absolutePath
attachment.disposition = org.apache.commons.mail.EmailAttachment.ATTACHMENT
attachment.description = 'Stuff'
attachment.name = 'stuff.txt'
// Attach the attachment
email.attach(attachment)
// Send the email
email.send()
// Clean up
file.delete()
Importing IMPEX
If you have an access to the Groovy Script console, you are definetely have an access to Impex Import. However, for some tasks, the impex script itself is dynamic and created dynamically. For these tasks, the following code can be useful:import de.hybris.platform.util.CSVConstants
import de.hybris.platform.servicelayer.impex.ImpExResource
import de.hybris.platform.servicelayer.impex.ImportResult
import de.hybris.platform.servicelayer.impex.impl.StreamBasedImpExResource
importImpex("INSERT Language;isocode;active\n;test;true")
def importImpex(String content) {
final ImpExResource mediaRes = new StreamBasedImpExResource(new ByteArrayInputStream(content.getBytes()), CSVConstants.HYBRIS_ENCODING)
importService.importData(mediaRes)
}
import de.hybris.platform.servicelayer.impex.ImpExResource
import de.hybris.platform.servicelayer.impex.ImportResult
import de.hybris.platform.servicelayer.impex.impl.StreamBasedImpExResource
importImpex("INSERT Language;isocode;active\n;test;true")
def importImpex(String content) {
final ImpExResource mediaRes = new StreamBasedImpExResource(new ByteArrayInputStream(content.getBytes()), CSVConstants.HYBRIS_ENCODING)
importService.importData(mediaRes)
}
Print all properties of an object
result = spring.getBean("flexibleSearchService").search("select {pk} from {Language}")
// properties
result.properties.each { println "$it.key -> $it.value" }
// properties
result.properties.each { println "$it.key -> $it.value" }
Print all methods of an object
a = spring.getBean("flexibleSearchService").search("select {pk} from {Language}");
dumpOut a
def dumpOut( clz ) {
clz.metaClass.methods.each { method ->
println "${method.returnType.name} ${method.name}( ${method.parameterTypes*.name.join( ', ' )} )"
}
}
dumpOut a
def dumpOut( clz ) {
clz.metaClass.methods.each { method ->
println "${method.returnType.name} ${method.name}( ${method.parameterTypes*.name.join( ', ' )} )"
}
}
Show the hybris type tree
import java.util.*;
flexibleSearch = spring.getBean("flexibleSearchService")
result = flexibleSearch.search (/select {pk} from {ComposedType}/).getResult()
Tree tree = new Tree();
result.each {
Node node = new Node(it.getCode(), it.getSuperType()?.getCode());
type = it.getClass().getSimpleName();
type = type.replace("ComposedTypeModel", "<Composed>");
type = type.replace("RelationMetaTypeModel", "<Relation>");
type = type.replace("EnumerationMetaTypeModel", "<ENUM>");
type = type.replace("TypeModel", "");
node.setDetails(type);
tree.getElements().add(node);
}
for (element in tree.getElements()) {
node1 = tree.find(element.getValue());
node2 = tree.find(element.getParentValue());
if (node1 != null) { node1.setParent(node2); }
if (node2 != null) { node2.addChild(node1); }
if (element.getParentValue() == null) { root = node1; }
}
int level = 0;
printANode(0, root);
displaySubTree(tree, level, root);
void printANode(level, Node item) {
print "."*level;
println item.getValue() + "(" + item.getDetails() + ")";
}
void displaySubTree(Tree tree, int level, Node node)
{
List<Node> subItems = node.getChildren();
for (item in subItems) {
printANode(level+1, item);
displaySubTree(tree, level+1, item);
}
}
public class Tree
{
List<Node> elements;
public List<Node> getElements() { return elements; }
public Tree() {
elements = new ArrayList();
}
public void add (Node element) {
elements.add(element);
}
public Node find(String value) {
for (it in elements) { if (it.getValue() == value) { return it; } }
}
}
public class Node
{
private Node parent = null;
private List<Node> children = null;
private String details = "";
private String value = "";
private String parentValue = "";
public Node(String value, String parent)
{
this.children = new ArrayList<>();
this.value = value;
this.parentValue = parent;
}
public setDetails(String nodeDetails)
{
details = nodeDetails;
}
public getDetails() { return details; }
public List<Node> getChildren() {
return children;
}
public void addChild(Node child)
{
children.add(child);
child.addParent(this);
}
public addParent (Node parentNode)
{
parent = parentNode;
}
public getValue () {
return value;
}
public String getParentValue() {
return parentValue;
}
public setParent(Node node)
{
parent = node;
}
}
flexibleSearch = spring.getBean("flexibleSearchService")
result = flexibleSearch.search (/select {pk} from {ComposedType}/).getResult()
Tree tree = new Tree();
result.each {
Node node = new Node(it.getCode(), it.getSuperType()?.getCode());
type = it.getClass().getSimpleName();
type = type.replace("ComposedTypeModel", "<Composed>");
type = type.replace("RelationMetaTypeModel", "<Relation>");
type = type.replace("EnumerationMetaTypeModel", "<ENUM>");
type = type.replace("TypeModel", "");
node.setDetails(type);
tree.getElements().add(node);
}
for (element in tree.getElements()) {
node1 = tree.find(element.getValue());
node2 = tree.find(element.getParentValue());
if (node1 != null) { node1.setParent(node2); }
if (node2 != null) { node2.addChild(node1); }
if (element.getParentValue() == null) { root = node1; }
}
int level = 0;
printANode(0, root);
displaySubTree(tree, level, root);
void printANode(level, Node item) {
print "."*level;
println item.getValue() + "(" + item.getDetails() + ")";
}
void displaySubTree(Tree tree, int level, Node node)
{
List<Node> subItems = node.getChildren();
for (item in subItems) {
printANode(level+1, item);
displaySubTree(tree, level+1, item);
}
}
public class Tree
{
List<Node> elements;
public List<Node> getElements() { return elements; }
public Tree() {
elements = new ArrayList();
}
public void add (Node element) {
elements.add(element);
}
public Node find(String value) {
for (it in elements) { if (it.getValue() == value) { return it; } }
}
}
public class Node
{
private Node parent = null;
private List<Node> children = null;
private String details = "";
private String value = "";
private String parentValue = "";
public Node(String value, String parent)
{
this.children = new ArrayList<>();
this.value = value;
this.parentValue = parent;
}
public setDetails(String nodeDetails)
{
details = nodeDetails;
}
public getDetails() { return details; }
public List<Node> getChildren() {
return children;
}
public void addChild(Node child)
{
children.add(child);
child.addParent(this);
}
public addParent (Node parentNode)
{
parent = parentNode;
}
public getValue () {
return value;
}
public String getParentValue() {
return parentValue;
}
public setParent(Node node)
{
parent = node;
}
}
Print hybris type stats
The following code prints a number of items for each hybris type.import java.util.*;
import java.lang.*;
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery
import de.hybris.platform.hac.facade.impl.DefaultFlexibleSearchFacade;
import de.hybris.platform.servicelayer.search.SearchResult;
flexibleSearch = spring.getBean("flexibleSearchService")
flexibleSearchFacade = new DefaultFlexibleSearchFacade();
typeService = spring.getBean("typeService");
result = flexibleSearch.search (/select {pk} from {ComposedType}/).getResult()
Tree tree = new Tree();
result.each {
Node node = new Node(it.getCode(), it.getSuperType()?.getCode());
type = it.getClass().getSimpleName();
isabstract = it.getAbstract() ? "<abstract>":"";
isjaloonly = it.getJaloonly() ? "<jaloonly>":"";
type = type.replace("ComposedTypeModel", "<Composed>");
type = type.replace("RelationMetaTypeModel", "<Relation>");
type = type.replace("EnumerationMetaTypeModel", "<ENUM>");
type = type.replace("TypeModel", "");
node.setDetails(type+isabstract+isjaloonly);
tree.getElements().add(node);
}
for (element in tree.getElements()) {
node1 = tree.find(element.getValue());
node2 = tree.find(element.getParentValue());
if (node1 != null) { node1.setParent(node2); }
if (node2 != null) { node2.addChild(node1); }
if (element.getParentValue() == null) { root = node1; }
}
displaySubTree(tree, 0, root, root.getValue());
void printANode(level, Node item, String history) {
count = "-";
if (!item.getNotLeaf() && !item.getDetails().contains("<abstract>")
&& !item.getDetails().contains("<jaloonly>")) {
count = calculateCount(item.getValue())
}
println history + "\t" + item.getValue() + "(" + item.getDetails() + ") \t"+count;
}
void displaySubTree(Tree tree, int level, Node node, String history)
{
List<Node> subItems = node.getChildren();
if (subItems.size() == 0) {
printANode(level, node, history);
}
for (item in subItems) {
printANode(level+1, item, history );
if (item.getChildren().size() != 0) {
displaySubTree(tree, level+1, item, history + "=>" + item.getValue());
}
}
}
public class Tree
{
List<Node> elements;
public List<Node> getElements() { return elements; }
public Tree() {
elements = new ArrayList();
}
public void add (Node element) {
elements.add(element);
}
public Node find(String value) {
for (it in elements) { if (it.getValue() == value) { return it; } }
}
}
public class Node
{
private Node parent = null;
private List<Node> children = null;
private String value;
private String details = "";
private String parentValue = "";
private Boolean notLeaf = false;
public Node(String value, String parent)
{
this.children = new ArrayList<>();
this.value = value;
this.parentValue = parent;
}
public setNotLeaf(Boolean itIsNotALeaf) {
notLeaf = itIsNotALeaf;
}
public getNotLeaf(Boolean itIsNotALeaf) {
return notLeaf;
}
public List<Node> getChildren() {
return children;
}
public void addChild(Node child)
{
children.add(child);
child.addParent(this);
}
public addParent (Node parentNode)
{
parent = parentNode;
}
public getValue () {
return value;
}
public String getParentValue() {
return parentValue;
}
public setParent(Node node)
{
parent = node;
}
public getParent()
{
return parent;
}
public setDetails(String nodeDetails)
{
details = nodeDetails;
}
public getDetails() { return details; }
}
String calculateCount(component) {
query = "select count({pk}) from {"+component+"}";
FlexibleSearchQuery fquery = new FlexibleSearchQuery(query);
fquery.setResultClassList(Arrays.asList(String.class));
fquery.setCount(1);
SearchResult<String> result = flexibleSearch.search(fquery);
return (result.getResult()?.get(0));
}
import java.lang.*;
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery
import de.hybris.platform.hac.facade.impl.DefaultFlexibleSearchFacade;
import de.hybris.platform.servicelayer.search.SearchResult;
flexibleSearch = spring.getBean("flexibleSearchService")
flexibleSearchFacade = new DefaultFlexibleSearchFacade();
typeService = spring.getBean("typeService");
result = flexibleSearch.search (/select {pk} from {ComposedType}/).getResult()
Tree tree = new Tree();
result.each {
Node node = new Node(it.getCode(), it.getSuperType()?.getCode());
type = it.getClass().getSimpleName();
isabstract = it.getAbstract() ? "<abstract>":"";
isjaloonly = it.getJaloonly() ? "<jaloonly>":"";
type = type.replace("ComposedTypeModel", "<Composed>");
type = type.replace("RelationMetaTypeModel", "<Relation>");
type = type.replace("EnumerationMetaTypeModel", "<ENUM>");
type = type.replace("TypeModel", "");
node.setDetails(type+isabstract+isjaloonly);
tree.getElements().add(node);
}
for (element in tree.getElements()) {
node1 = tree.find(element.getValue());
node2 = tree.find(element.getParentValue());
if (node1 != null) { node1.setParent(node2); }
if (node2 != null) { node2.addChild(node1); }
if (element.getParentValue() == null) { root = node1; }
}
displaySubTree(tree, 0, root, root.getValue());
void printANode(level, Node item, String history) {
count = "-";
if (!item.getNotLeaf() && !item.getDetails().contains("<abstract>")
&& !item.getDetails().contains("<jaloonly>")) {
count = calculateCount(item.getValue())
}
println history + "\t" + item.getValue() + "(" + item.getDetails() + ") \t"+count;
}
void displaySubTree(Tree tree, int level, Node node, String history)
{
List<Node> subItems = node.getChildren();
if (subItems.size() == 0) {
printANode(level, node, history);
}
for (item in subItems) {
printANode(level+1, item, history );
if (item.getChildren().size() != 0) {
displaySubTree(tree, level+1, item, history + "=>" + item.getValue());
}
}
}
public class Tree
{
List<Node> elements;
public List<Node> getElements() { return elements; }
public Tree() {
elements = new ArrayList();
}
public void add (Node element) {
elements.add(element);
}
public Node find(String value) {
for (it in elements) { if (it.getValue() == value) { return it; } }
}
}
public class Node
{
private Node parent = null;
private List<Node> children = null;
private String value;
private String details = "";
private String parentValue = "";
private Boolean notLeaf = false;
public Node(String value, String parent)
{
this.children = new ArrayList<>();
this.value = value;
this.parentValue = parent;
}
public setNotLeaf(Boolean itIsNotALeaf) {
notLeaf = itIsNotALeaf;
}
public getNotLeaf(Boolean itIsNotALeaf) {
return notLeaf;
}
public List<Node> getChildren() {
return children;
}
public void addChild(Node child)
{
children.add(child);
child.addParent(this);
}
public addParent (Node parentNode)
{
parent = parentNode;
}
public getValue () {
return value;
}
public String getParentValue() {
return parentValue;
}
public setParent(Node node)
{
parent = node;
}
public getParent()
{
return parent;
}
public setDetails(String nodeDetails)
{
details = nodeDetails;
}
public getDetails() { return details; }
}
String calculateCount(component) {
query = "select count({pk}) from {"+component+"}";
FlexibleSearchQuery fquery = new FlexibleSearchQuery(query);
fquery.setResultClassList(Arrays.asList(String.class));
fquery.setCount(1);
SearchResult<String> result = flexibleSearch.search(fquery);
return (result.getResult()?.get(0));
}
© Rauf Aliev, November 2017
Tyler
1 December 2017 at 23:19
great, thanks for sharing