Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AF-2771: Dashbuilder Programmatic Layout API #1119

Merged
merged 7 commits into from Mar 26, 2021
Merged

Conversation

jesuino
Copy link
Contributor

@jesuino jesuino commented Mar 18, 2021

JIRA: https://issues.redhat.com/browse/AF-2771

MERGE WITH:kiegroup/droolsjbpm-build-bootstrap#1619

This is a PR to bring a new programmatic way of creating dashboards to Dashbuilder.

Besides this, it also correct many small issues with he existing API, allows the users to export the Dashboard to a ZIP file that can run on Dashbuilder Runtime and adds a development mode to Dashbuilder Runtime!

  • Programatic Dashboards

To create programmatic dashboards first you must build appformer/dashbuilder/dashbuilder-shared/dashbuilder-dsl using mvn clean install then you can add the dependency org.dashbuilder:dashbuilder-dsl:7.52.0-SNAPSHOT to your project.

The API has 5 main components

  1. Data Sets: The API for data sets has as entry point the class org.dashbuilder.dataset.def.DataSetDefFactory which allows you to create your own data set definition. You can also pure Java data set using the class DataSetFactory:, for example:
DataSetFactory.newDataSetBuilder()
              .column("NAME", ColumnType.LABEL)
              .column("AGE", ColumnType.NUMBER)
              .row("William", "32")
              .row("Antonio", 5)
              .buildDataSet();
  1. Components : Components can be used in a dashboard page to display a data set or a static information. The entry point to create components is the class org.dashbuilder.dsl.factory.component.ComponentFactory. From there you can refer to components in your local file system or build displayers components. For displayer components notice that we need a factory to build the settings, the factory is class: org.dashbuilder.displayer.DisplayerSettingsFactory, where you can build the settings for your displayer. Bear in mind that all classes that uses a displayer will require a data set to be built, otherwise an exception will be thrown when exporting the dashboard;
  2. Page: You can build pages composed of the components mentioned in 2. Pages have rows that can have columns and finally components. Using the class org.dashbuilder.dsl.factory.page.PageFactory allow make it easy for you to create any page component;
  3. Navigation: You can create the pages navigation using org.dashbuilder.dsl.factory.navigation.NavigationFactory. This class can be used to define the menu of pages that will be displayed in Dashbuilder Runtime;
  4. Dashboard: This is the class that clues everything. It can be created using org.dashbuilder.dsl.factory.dashboard.DashboardFactory.
  • All these classes have builders that can be used instead the factory

Once you have your Dashboard object, you can export it to a file using the class org.dashbuilder.dsl.serialization.DashboardExporter.

Here's very simple Dashboard using the above classes:

import org.dashbuilder.dataset.*
import org.dashbuilder.displayer.DisplayerSettings;
import org.dashbuilder.dsl.factory.component.ComponentFactory;
import org.dashbuilder.dsl.factory.dashboard.DashboardFactory;
import org.dashbuilder.dsl.model.*
import org.dashbuilder.dsl.serialization.*

import static java.util.Arrays.asList;
import static org.dashbuilder.dataset.DataSetFactory.newDataSetBuilder;
import static org.dashbuilder.displayer.DisplayerSettingsFactory.newBarChartSettings;
import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.*;
import static org.dashbuilder.dsl.factory.page.PageFactory.*;

public class SimpleDashboard {

    public static void main(String[] args) {
        DataSet dataSet = newDataSetBuilder().column("Country", ColumnType.LABEL)
                                             .column("Population", ColumnType.NUMBER)
                                             .row("Brazil", "211")
                                             .row("United States", "328")
                                             .row("Cuba", "11")
                                             .row("India", "1366")
                                             .row("China", "1398")
                                             .buildDataSet();

        DisplayerSettings populationBar = newBarChartSettings().subType_Column()
                                                               .width(800)
                                                               .height(600)
                                                               .dataset(dataSet)
                                                               .column("Country")
                                                               .column("Population")
                                                               .buildSettings();
        Page page = page("Countries Population",
                         row("<h3> Countries Population </h3>"),
                         row(ComponentFactory.displayer(populationBar)));
        Navigation navigation = navigation(group("Countries Information", item(page)));

        Dashboard populationDashboard = DashboardFactory.dashboard(asList(page), navigation);

        DashboardExporter.get().export(populationDashboard, 
                                       "/path/to/export.zip", 
                                       ExportType.ZIP);
    }

}

It will generate the following dashboard:

image

Now, this PR is much more than this, it adds a "dev mode" to Dashbuilder Runtime. This way while you develop and export the ZIP it will automatically update on Dashbuilder Runtime. This mode also upload automatically the list of dashboard in multi mode automatically. It is not for production, once the work is done the recommendation is go to produce with Dashbuilder using STATIC mode.

This is model list update

model_update

And dashboards can also be automatically updated:

dashboard_update

This is can be enabled using the system property "dashbuilder.dev=true".

A sample dashboard can also be found on test DashboardZipSerializerTest.

Thanks!

@jesuino
Copy link
Contributor Author

jesuino commented Mar 19, 2021

jenkins retest this

@jesuino
Copy link
Contributor Author

jesuino commented Mar 19, 2021

Hello @caponetto and @sthundat could you please review this PR?

Thanks!

@barboras7
Copy link
Contributor

jenkins execute fdb

@sthundat sthundat requested review from barboras7 and removed request for sthundat March 22, 2021 09:25
@@ -30,6 +31,7 @@
import org.dashbuilder.client.error.DefaultRuntimeErrorCallback;
import org.dashbuilder.client.perspective.NotFoundPerspective;
import org.dashbuilder.client.resources.i18n.AppConstants;
import org.dashbuilder.shared.event.UpdatedRuntimeModelEvent;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why adding unused imports? Both UpdatedRuntimeModelEvent and Observes

<artifactId>gson</artifactId>
</dependency>


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra empty line

*/
public interface DashboardValidator {

static final DashboardValidator instance = new DashboardValidatorImpl();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static, final and public modifiers have no use in an interface

class DashboardValidatorImpl implements DashboardValidator {

private static final String MISSING_NAVIGATION_ITEM = "Navigation item %s has no corresponding page";
private static final String VALIDE_NAVIGATION = "Navigation is valid.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static final String VALIDE_NAVIGATION = "Navigation is valid.";
private static final String VALID_NAVIGATION = "Navigation is valid";

To keep the messages consistent, I would either remove the "." here or add it into other messages

}

@Test
public void testSucessfulValidation() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void testSucessfulValidation() {
public void testSuccessfulValidation() {

@barboras7
Copy link
Contributor

Hi William,

these are the observations that I have found during my testing. Since there is a lot to test, I will continue tomorrow morning, but I can say now that "happy path" scenarios work.

  1. I am getting the following error:20:29:19,325 ERROR [org.dashbuilder.backend.services.impl.RuntimeModelRegistryImpl] (EE-ManagedExecutorService-default-Thread-1) File does not have a valid structure: /home/bsiskova/dashboards/export.zip 20:29:19,325 ERROR [org.dashbuilder.backend.RuntimeModelWatcherServiceManager] (EE-ManagedExecutorService-default-Thread-1) Error registering model Not a valid file structure. First time, when I run my application (basically, it is similar to what you provided above ^ as an example, I just have multiple pages there), everything works without an error. When I run it the second time, I am getting this error (even when I don't change anything) and the dashboard is actually working.
  2. When I deploy the business central from the build on this PR, the business central is successfully deployed but after login, I only get the "Loading application" and it never gets to the home screen. I guess there was some issue with the build, but I want to be sure this is not happening to you.
  3. Would it be possible to avoid unnecessary logging? The log says - updated, then removed, then updated again (when a dashboard is updated)
    20:34:54,865 INFO [org.dashbuilder.backend.RuntimeModelListener] (EE-ManagedExecutorService-default-Thread-1) Updated model export
    20:34:54,865 INFO [org.dashbuilder.backend.RuntimeModelListener] (EE-ManagedExecutorService-default-Thread-1) Removed model export
    20:34:54,873 INFO [org.dashbuilder.backend.RuntimeModelListener] (EE-ManagedExecutorService-default-Thread-1) Updated model export
  4. Why is the message in the log above "Updated model export"? Since in the UI, we use the naming "dashboard", this might not be helpful for the user to have the word "model" there. The same applies for the messages in log from the RuntimeModelWatcherServiceManager
  5. When a user tries to use a data set with no data (just initialized by DataSet dataSet1 = newDataSetBuilder().buildDataSet();), the building of the dashboard will fail and the user gets the following message Displayer settings dataset lookup not specified. Although I know that this message was not added as part of this PR, it might be good to consider some other wording so that the user can understand what is wrong.
  6. I was not able to create a bubble chart, getting the following error. The data set I used is the same as in your example.
    Screenshot from 2021-03-23 17-29-22
  7. If I create two pages and just use one in the dashboard, I get the following error
    Exception in thread "main" java.lang.IllegalArgumentException: There are validation errors, check logs for more details at org.dashbuilder.dsl.serialization.DashboardExporter.validate(DashboardExporter.java:71) at org.dashbuilder.dsl.serialization.DashboardExporter.export(DashboardExporter.java:53) at SimpleDashboard.main(SimpleDashboard.java:59)
    Is this the correct behavior? It was really difficult to figure out why there was this error. At least, some message in the log would be helpful.
  8. The external components are not loaded correctly. For example, the dashbuilder logo in the Logo Component (from your examples) does not show up correctly in the Dashbuilder Runtime
    Screenshot from 2021-03-23 20-21-33
  9. If the user has multiple pages in the dashboard and they are viewing one of them, let's say MyPage1, if they rerun their program and the dashboard is rebuild, they are redirected to the home screen of Dashbuilder Runtime. I think it would be more useful to stay in the page that they were viewing, so that after the reloading of the dashboard, they can see how the page changes immediately.

Also, I have some questions:

  1. Is it possible to create navigation with multiple groups? Let's say when I want to create a menu that is similar to the one in the business central.
  2. Is it possible to use all kinds of data set? Until now, I was creating data the same way as you in your example. But, if I have Prometheus running and I want to create a Prometheus data set, can I do it using this API?

I am sorry if these questions are too simple, but since there is not much time to test the PR, I rather ask then spend too much time figuring out myself 🙂

Also, if it will be of any help to you, this is (with some small changes now and then) the code that I was using to test the PR (if you need to reproduce something)

Let me know if you need some more information on some of my points 🙂

@jesuino
Copy link
Contributor Author

jesuino commented Mar 24, 2021

Hello @barboras7

Thank you so much for your detailed review, really appreciate. Please find my comments inline

  1. This error happens because we open the stream and start writing the ZIP content and meanwhile the watches grabs the partial content leading to exception - a solution I am writing the ZIP to a temp file and not observing MODIFY events, only delete and create this should result in a clean log and no more misleading errors messages;

  2. This PR should not impact Business Central, but I will check and let you know;

  3. That happens because the copy/move operations are not atomic, it fires the UPDATE watch. What I did to improve this is only listen to CREATE/DELETE and ignore UPDATE. Since mv is actually a delete/copy so it should work okay;

  4. Changed to "dashboard" in logs

  5. I agree completely, this happens because the Dataset JSON marshaller excludes data sets when it is empty.. I changed the message to "Displayer settings data set lookup not specified or data set is empty." for now, for later we can improve data set validation but using other JIRA;

  6. The bubble chart settings requires at least 3 columns: For X, Y and radius. Now the trick is that the following columns are retrieved: 1 is the category name, 2 is X position in the chart, column 3 is Y and column 4 should be the bubble color, but it is ignored for the current chart libraries (I did it to keep compatibility with Google chart - the previous library) and finally 4 is the column radius. Having this said, the following code should work for a Bubble chart - notice how I have to add duplicated column for radius:

DataSet dataSet = DataSetFactory.newDataSetBuilder()
                                        .column("CAT", ColumnType.LABEL)
                                        .column("X", ColumnType.NUMBER)
                                        .column("Y", ColumnType.NUMBER)
                                        .column("IGONORED", ColumnType.LABEL)
                                        .column("R", ColumnType.NUMBER)
                                        .row("A", "1", "1", "IGNORED", "1")
                                        .row("B", "2", "2", "IGNORED", "2")
                                        .row("C", "3", "3", "IGNORED", "3")
                                        .row("D", "4", "4", "IGNORED", "4")
                                        .buildDataSet();
DisplayerSettings settings = DisplayerSettingsFactory.newBubbleChartSettings()
                                .dataset(dataSet)
                                .buildSettings();
Page page = page("test", row(settings));
Dashboard dashboard = dashboard(asList(page));

This generates the following chart

image

Fixing it would impact all reports in Business Central, so we need to live with this glitch for now.

Talking about column constraints, an improvement that could be done in a near future is validate displayer settings based on DisplayerConstraints. No validation was planned for this version, but I added a few to avoid a "trial and error" API. I could simply do this now also because it all happens on client side, after the dashboard is rendered and it changes from chart API to chart API - but it is possible to do it for the programmatic API.

  1. This is not the expected behavior, in logs you should see the actual cause. If your page is using a data set that is not included then it will indeed fail. Please let me know the code that failed.

  2. The following simple page works for:

Page page = page("test", row(ComponentFactory.logo("https://www.redhat.com/cms/managed-files/styles/xlarge/s3/red-hat-logo-a-sample.png?itok=PJP_urGJ")));

Please let me know which code you used for the logo.

9.That is a great suggestion, thanks! I did changed Dashbuilder to support it - let me know if it works for you

Is it possible to create navigation with multiple groups? Let's say when I want to create a menu that is similar to the one in the business central.

I just forgot to allow multiple groups creation! Now when creating the navigation you can pass multiple groups. Thanks for noticing it.

Is it possible to use all kinds of data set? Until now, I was creating data the same way as you in your example. But, if I have Prometheus running and I want to create a Prometheus data set, can I do it using this API?

Yes. the only trick at the moment is Runtime Server data set, because a new dependency will needed to be added to your project. This happens because execution server is not a CORE data set, the implementation changes from BC to Dashbuilder Runtime!

The entry point for all data sets is the DataSetDefFactory class. Here's a simple Prometheus dashboard with auto refresh:

DataSetDef prometheus = DataSetDefFactory.newPrometheusDataSetDef()
                                         .uuid(UUID.randomUUID().toString())
                                         .serverUrl("http://localhost:9090")
                                         .query("prometheus_http_requests_total")
                                         .buildDef();

DisplayerSettings settings = DisplayerSettingsFactory.newBarChartSettings()
                                                     .subType_Column()
                                                     .dataset(prometheus.getUUID())
                                                     .group("handler")
                                                     .column("handler")
                                                     .margins(0, 0, 60, 0)
                                                     .column("VALUE", AggregateFunctionType.SUM)
                                                     .refreshOn(5, false)
                                                     .buildSettings();

Page page = page("p1", row("<h1>Http Requests</h1>"), row(settings));

This will result in the following page:

image

Kindly let me know your feedback - these were all great points, I really appreciate.

@jesuino
Copy link
Contributor Author

jesuino commented Mar 24, 2021

jenkins execute fdb

@barboras7
Copy link
Contributor

Hi William,

thanks for your answers.

  1. Thanks, I am getting just INFO level instead of ERRORs.

  2. FBD has not finished yet, but from the Compile Downstream, the Business Central is still not working. Please, let me know when you have more information about this.

3., 4., 5. These all work as expected, thanks.

  1. It makes sense that there's no time to implement the validation now. Also, for future, maybe it would be enough to just provide specific error messages for each type of chart (Something like "There was an error creating bubble chart. Following are the constraints you should follow to create the chart successfully: ..."). Anyway, I can create a Jira for this and you can decide later how this should be handled.

  2. I am not able to reproduce this error with the latest code changes anymore so I am considering this as fixed (although no idea what actually happened)

  3. I am sorry, I should have provided more information for this. Actually, the logo component works for me. What is not working is following:

  • I took the simplest_component from your examples from examples
  • I used the following code to create and external component and use it in page - see pastebin
  • I had the following error in the logs:
    15:32:24,535 INFO [org.dashbuilder.external.ExternalComponentServlet] (default task-3) Not able to find component asset export-simple3/simplest_component/scripts/index.js
    15:32:24,538 INFO [org.dashbuilder.external.ExternalComponentServlet] (default task-3) Not able to find component asset export-simple3/simplest_component/images/db_logo.png
  • without setting any property for the component, I believe that the logo should be displayed correctly
  • this is what I am seeing:
    Screenshot from 2021-03-24 15-32-26
  • in business central, using the same path for external components (on 7.10.0 version) I am seeing this:
    Screenshot from 2021-03-24 15-30-55
    hence the logo is correctly displayed
  1. This is working great, thanks!

Also, I have some other observations I found today:

  1. I noticed that in the business cental, it is possible to create pages with more elements. Under navigation, there are things like carousel, menu bar, etc. Will there be support for these also in this programmatic API?
  2. There is an inconsistent behavior between business central and dashbuilder runtime. In BC, if you create a page and don't use it in group in navigation, it is shown under Runtime Dashboards. Here, in the programmatic API, if you create a page and don't use it, it is just not exported in the .zip file (when you are exporting also pages that are used in navigation). Would it be possible to somehow "register" all pages that are built when creating a .zip and then show them in the "Runtime Dashboards"? The ones that are used in navigation will be in navigation and the rest would be in the "Runtime Dashboards".
  3. I noticed that it is possible to create two navigation groups with the same name. I don't know if this could cause any issues, just letting you know.
  4. I tried to use the exported .zip file in the business central. It was possible to upload it, but nothing actually happened (There was a notification about successful upload, but no information about which files where uploaded and the pages from the zip file were not visible in the Pages Editor). I used the 7.10.0 Business Central as the Business Central built in this PR does not work for me. The zip file was created from this code.

Please, let me know if you need more information from me to reproduce some of the behaviors I described. Thank you.

@jesuino
Copy link
Contributor Author

jesuino commented Mar 24, 2021

Hello Barbora,

Thanks again for your feedback.

  1. The CDB BC is not expected to work because it lacks GWT compilation, but the FDB one should work. I downloaded it locally and it seems to work. The way I install is replacing the business-central WAR with an existing one in an already configured jbpm server installation

  2. From the error looks like the image was not included in the component directory. Now notice that if you have partition turned on then the assets won't be in the component dir, but in a dir for the dashboard, which is inside components dir. I made an example with external component and it works:

  3. https://github.com/jesuino/dashbuilder-docker/blob/master/demos/dashbuilder_dev_mode/dashbuilder-dsl-dashboards/src/main/java/org/kie/dashbuilder/dashboards/SimpleExternalComponent.java

Regarding the new items:

  1. Navigation components were not added to this version, but it should be added later. I was afraid that we would have too code to test and review for this specific PR;

  2. That's a bad behavior, orphan pages should be added to the "Runtime Dashboards" group, which was created for this purpose. However, I tried to reproduce with the code below but it worked:

    @Override
    public Dashboard build() {
        Page p1 = page("Page 1",
                         row("<h3>This is page 1</h3>"));
        Page p2 = page("Page 2",
                         row("<h3>This is page 2</h3>"));

        Navigation navigation = navigation(group("Page 1 Navigation Group", item(p1)));

        return DashboardBuilder.newBuilder(asList(p1, p2))
                               .navigation(navigation)
                               .build();
    }

I have some sample dashboards in my demos repo: https://github.com/jesuino/dashbuilder-docker/tree/master/demos/dashbuilder_dev_mode/dashbuilder-dsl-dashboards/src/main/java/org/kie/dashbuilder/dashboards

  1. Thanks for letting me know, I created a validation rule for it, now duplicated groups will lead to exceptions.

  2. It worked for me, even with your test dashboard. But in any case, I would not recommend doing this in BC because the exported ZIP is focused to run on Runtime because Business Central will often have navigation conflict, which messes the main menu - It works, but I would not recommend.

Screenshot from 2021-03-24 18-06-45

Thanks and please let me know if I am missing anything!

@jesuino
Copy link
Contributor Author

jesuino commented Mar 24, 2021

jenkins execute fdb

@barboras7
Copy link
Contributor

Hello William,

thanks for the fixes.

  1. Should I create a Jira for adding the navigation components? Also, should I create another Jira for implementation of validation for charts (as we discussed earlier here)?
  2. I am sorry for this. I have probably forgotten to include the page in the dashboard (due to approaching code freeze, I was trying to do everything as fast as possible and probably just missed this 😞 ). You are right, it works as it should.
  3. Thank you. The validation works now.
  4. This might need further investigation but since you said that it is not recommended to import the .zip files created this way into Business Central, my suggestion is to leave this without further investigation since there's not much time left before the code freeze.

You really did a great job on this PR 🎉

@jesuino
Copy link
Contributor Author

jesuino commented Mar 25, 2021

Hello @barboras7 ,

Thank you so much for your great review and feedback.

  1. Please go ahead and create, I will be checking if we can include both features soon;
  2. Np at all, I do understand and I am really grateful that you found time to work on this big PR;
  3. yw
  4. I agree, thanks for understanding

Thanks again! \o/

Copy link
Member

@caponetto caponetto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jesuino, thanks for the PR!
I've left some comments, please check if they make sense.

@@ -51,7 +53,7 @@
void setSize(int chartWidth, int chartHeight);

void setMargin(int chartMarginTop, int chartMarginRight, int chartMarginBottom, int chartMarginLeft);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these extra whitespaces.

@@ -0,0 +1,3 @@
function sayHello() {
alert("NEVER, it is just the begging!")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
alert("NEVER, it is just the begging!")
alert("NEVER, it is just the beginning!")

Did you mean beginning?

@@ -0,0 +1 @@
<h1>Comp1</h1>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this is a test resource, I think we need to add the copyright header to this file.

@@ -0,0 +1,3 @@
function sayHello() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this is a test resource, I think we need to add the copyright header to this file.

Comment on lines 149 to 152
//Use this to export this dashboard to run on Dashbuilder runtime
// org.dashbuilder.dsl.serialization.DashboardExporter.get().export(db,
// "/tmp/dashbuilder/models/Population.zip",
// org.dashbuilder.dsl.serialization.DashboardExporter.ExportType.ZIP);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing this commented code.

}

private static DashboardZipSerializer serializerFor(ExportType type) {
// only ZIP us supported at the moment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// only ZIP us supported at the moment
// only ZIP is supported at the moment

Typo here.


writeNavigation(zos, dashboard.getNavigation());

writeContent(zos, DATA_SETS_BASE + "readme.md", "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting "readme.md" into a constant.

Path path = Paths.get(filePath);
if (path.toFile().exists()) {
try {
writeContent(zos, DATA_SETS_PATH + def.getUUID() + ".csv", Files.readAllBytes(path));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting ".csv" into a constant.

Comment on lines 90 to 95
if (path.startsWith(LAYOUTS_PATH) && path.endsWith("perspective_layout")) {
LayoutTemplate template = gson.fromJson(content, LayoutTemplate.class);
pages.add(Page.create(template));
}

if (path.startsWith(DATA_SETS_PATH) && path.endsWith("dset")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting "dset" and "perspective_layout" into constants.
Lines 190 and 198 would need them.

Map<String, String> entriesContent = new HashMap<>();
Path zipTemp;
try {
zipTemp = Files.createTempFile("dashboard", "zip");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting these hardcoded strings into constants.

@caponetto
Copy link
Member

caponetto commented Mar 26, 2021

Hi @jesuino, can you please take a look at the issues that SonarCloud has raised?
Also, we need a PR for droolsjbpm-build-bootstrap. See this comment #1119 (comment).

@jesuino
Copy link
Contributor Author

jesuino commented Mar 26, 2021

Hello @caponetto

I made most of the suggested changes by sonar cloud and created the PR for our BOM:

kiegroup/droolsjbpm-build-bootstrap#1619

I didn't make all changes because:

  1. I am following some methods name conventions according to what was done before (methods with underscore)
  2. I like to rethrow some checked dependencies as runtime exception and sonar cloud seems to not like that

Thanks!

@jesuino
Copy link
Contributor Author

jesuino commented Mar 26, 2021

jenkins execute cdb

@jesuino
Copy link
Contributor Author

jesuino commented Mar 26, 2021

jenkins execute fdb

Copy link
Member

@caponetto caponetto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, @jesuino! Thanks!

@jesuino
Copy link
Contributor Author

jesuino commented Mar 26, 2021

The "Security Hotspot" raised by Sonar Cloud makes sense, but I have two points:

  • Added a limitation to the number of entries that can be read from the imported ZIP;
  • The deserialize method for ZIP is not supported as commented in the code and will be documented.

image

What we did to avoid any security breach was to make the deserialize method NON PUBLIC and making it unsupported at the moment.

Thanks.

@ederign ederign merged commit 245867b into kiegroup:master Mar 26, 2021
@sonarcloud
Copy link

sonarcloud bot commented Mar 26, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants