GithubHelp home page GithubHelp logo

microfocus / almoctanejavarestsdk Goto Github PK

View Code? Open in Web Editor NEW
16.0 15.0 19.0 3.24 MB

Support for the Octane REST API in Java. develop branch is used for lastest code

License: Other

Java 99.94% HTML 0.06%
octane

almoctanejavarestsdk's Introduction

ALM Octane REST API Java SDK

Maven

<dependency>
    <groupId>com.microfocus.adm.almoctane.sdk</groupId>
    <artifactId>sdk-src</artifactId>
    <version>24.1.5</version>
</dependency>

Gradle

compile group: 'com.microfocus.adm.almoctane.sdk', name: 'sdk-src', version: '24.1.5'

Introduction

A Java SDK that can be used to connect to ALM Octane's REST API. See the Javadoc for more information of how to use the SDK. See also the REST API documentation for more details about Octane's API.

This has multiple sub-projects:

  1. sdk-src which is the main source of the Java SDK
  2. sdk-integration-tests which can be run to test the SDK against your Octane server
  3. sdk-usage-examples which contain some simple examples as to how to use the SDK
  4. sdk-generate-entity-models-maven-plugin which contains a maven plugin that generates POJO's for your servers Octane entities see "Entity Generation"
  5. sdk-extension which provides some tools to access more of the sdk-src's underlying implementation

The easiest way to compile the project is to use maven and run the command:

mvn clean install

from the root directory.

Creating JavaDoc

In order to create javadoc run the following maven command from the sdk-src directory:

mvn javadoc:javadoc

This will create a javadoc site in the sdk-src/target/site/apidocs directory

Entity Generation

You can generate entities based on your server's metadata using the sdk-generate-entity-models-maven-plugin plugin. This plugin connects to your ALM Octane server using the given authentication credentials, shared space and work space and generates strongly typed entities that can be used instead of the generic out of the box entity that comes with the SDK.

To enable this, add the following to your project's POM file (assuming 16.1.100 being the SDK version):

 <build>
        <plugins>
            <plugin>
                <groupId>com.microfocus.adm.almoctane.sdk</groupId>
                <artifactId>sdk-generate-entity-models-maven-plugin</artifactId>
                <version>24.1.5</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <clientId>client_id</clientId>
                    <clientSecret>client_secret</clientSecret>
                    <server>http[s]://server[:port]</server>
                    <sharedSpace>SSID</sharedSpace>
                    <workSpace>WSID</workSpace>
                    <techPreview>boolean (default false)</techPreview>
                    <!--
                        By default the plugin will generate the sources to the generated-source directory under
                        the target.  If you wish to place this in a different place then use this parameter
                    -->
                    <!-- <generatedSourcesDirectory></generatedSourcesDirectory> -->
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.9.1</version>
                <executions>
                    <execution>
                        <id>addGeneratedEntitiesSources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <!--
                                  This assumes that you leave the configuration of the plugin above
                                  to use the maven generated-sources directory as the place where the generated
                                  sources will be
                                -->
                                <source>${project.build.directory}/generated-sources</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!--
                The sources need to be compiled using Java 8 at least.  Use this if this needs to 
                be explicit
            -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

Alternatively you can use the maven command line command to generate. See the maven documentation for more details as to how to do this.

Generated Directories

The generator will create three directories under the com.hpe.adm.nga.sdk package:

  • entities
  • enums
  • model

With the generated code. Do not edit the generated code since it will be overwritten each time you run a maven build.

Using the generated code

See the following example for how to use the generated code:

        final Octane octane = new Octane.Builder(...).build();
        final WorkItemRootEntityModel workItemRootEntityModel = octane.entityList(WorkItemRootEntityList.class).at(1001).get().execute();

        final EpicEntityModel rootEpic = octane.entityList(EpicEntityList.class).create().entities(Collections.singleton(
                new EpicEntityModel("rootepic", workItemRootEntityModel, Phases.EpicPhase.NEW)
        )).execute().iterator().next();
        final FeatureEntityModel featureEntityModel = octane.entityList(FeatureEntityList.class).create().entities(Collections.singleton(
                new FeatureEntityModel("feature1", Phases.FeaturePhase.NEW).setParent(rootEpic)
        )).execute().iterator().next();
        final DefectEntityList defectEntityList = octane.entityList(DefectEntityList.class);
        final DefectEntityModel defect = defectEntityList.create().entities(Collections.singleton(
                new DefectEntityModel("defect", featureEntityModel, Phases.DefectPhase.DEFERRED)
        )).execute().iterator().next();
        defect.setSeverity(Lists.Severity.HIGH).setDescription("this has been updated");
        defectEntityList.update().entities(Collections.singleton(defect)).execute();

Please note that due to the way that the Octane REST API works only a limited number of fields will be automatically retrieved from the server. Due to this the addFields method should be used to explicitly state which fields should be retrieved. You can see more information here

Logging

The SDK uses SLF4J internally for all logging. This means that the users of the library can control the logging framework used for the implementation. The easiest way is to add a maven dependency to such an implementation (slf4j-simple, log4j, logback etc.)

Example

    <dependencies>
        <dependency>
            <groupId>com.microfocus.adm.almoctane.sdk</groupId>
            <artifactId>sdk-src</artifactId>
            <version>24.1.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>

This will make the sdk use log4j as an slf4j implementation, configuring a log4j.xml in your project will also take effect on the sdk.

Space and Workspace admin

By various combinations of not setting the space id, or setting the space id and not the workspace id, the admin of those spaces can be accessed. See the TestSharedSpaceAdmin and TestWorkSpaceAdmin tests for examples of how these can be used.

Currently the admin sections are not available using generated entities - but the CRUD functions are available

What's New

  • CE 24.1.5

    • Fixed vulnerabilities from jetty
  • CE 24.1.4

    • Added support for SessionId authentication
  • CE 24.1.3

    • Fixed vulnerabilities from org.json and google-http-client
  • CE 24.1.2

    • Fixed extracting facts from business rules
    • Improved parsing of date fields
    • Replaced hardcoded unsupported characters check with java.lang.Character API (Vanilla SDK)
  • CE 24.1.1

    • ArrayFieldModel can now be used for fields containing generic JSONArray
  • CE 24.1

    • Object field model is now sent as JSON instead of String
  • CE 23.4

    • Added support for operating with business rules (see README)
  • 23.3.1

    • Fixed bug related to JSON Array response parsing
    • Fixed DateFieldModel bug related to the clear method
    • Updated licenses
  • 23.3.0

    • Query is now sent as an encoded string so that special characters are now supported for api data filtering
    • Fixed bug related to code generation based on ALM Octane entities containing special characters
    • Updated org.json to version 20230227
  • 16.1.100.3

    • Added new clearField method on generated models which sets the field value to null instead of removing it
  • 16.1.100.2

    • Added Query.NULL and Query.NULL_REFERENCE values for filtering not populated fields
  • 16.1.100.1

    • Added a new OctaneHttpClient using Jetty, for HTTP/2 support
  • 16.1.100

    • Fixed vulnerability by removing transitive dependency for apache-commons-text
  • 16.0.400.1

    • Fixed bug related to session cookie collision on parallel requests
  • 16.0.400

    • Fixed list entity bug related to pagination
    • Updated google client version to 1.42.0
    • Support multiple attachments in single requests
  • 16.0.300

    • Fixed ClassCastException on EmptyFieldModel Issue 133
    • Replaced / with _ in list name generation Issue 124
    • Added OctanePartialException message Issue 132
  • 15.1.60

    • Added support for Basic Authentication. If the Octane space parameter SUPPORTS_BASIC_AUTHENTICATION is set to true,
      when creating the Octane object, the class SimpleBasicAuthentication can be used in order to connect to Octane via basic authentication.
  • 15.1.40

    • EntityModel now has a toString() for easier logging. Enhancement 102
    • Added possibility to add a header to a single request and extend the current url. Enhancement 104
    • Added a way of setting:
  • 15.1.20

    • Enable entity generation using the tech preview api mode. Adds more entities and fields
    • Manipulate test scripts using the SDK. See TestExample in the sdk-usage-examples module for more information
    • Able to get the context for space and workspace admins
    • FIX for Bug 97. Logging uses the slf4j paradigm for formatting strings
    • Internal fix to enable OctaneClassFactory too be set by the Builder
  • 15.0.40.1

    • FIX for Bug 79. User defined lists are now created with a _ in front of the package name when using the generator to ensure Java convention is followed
  • 15.0.40

    • Get the server version using the SiteAdmin API. This matches the serverurl/admin/server/version REST call
    • The way that the API mode can be set has changed. It is now easier to set the technical preview by using the APIMode interface and default classes. Other modes can be set as well. See Javadoc for more details
  • 15.0.20

    • Lists are now created in their own classes. The package name is based on the list's logical name. This was necessary due to non-unique list names. In order to try to preserve backward compatibility the actual class name should be the same but are now in separate packages. That means that in the best case only imports need to be changed.
      • In addition to this list names need to conform to Java standards. If a list name starts with an illegal character such as a number then the name will start with a '$'.
    • Due to a bug on Octane - the run_history entity's ID is marked as an integer as opposed to a string. This causes an issue in the entity generation. Therefore the run_history entity will not be generated until this bug is fixed in Octane
  • 12.60.41

    • Float fields now supported via FloatFieldModel if they are enabled on the Octane server.
    • Change to maven group id: com.microfocus.adm.almoctane.sdk
  • 12.60.21

    • Fixed bug where etag header was not being set properly
    • Fixed null pointer if the sdk encountered un-parsable entity JSON
    • Octane.OctaneBuilder now has constructor that allows passing a specific instance of OctaneHttpClient for the Octane object
  • 12.55.32

    • Octane server errors will not be properly parsed into an ErrorModel object
    • ErrorModels from OctaneExceptions will now also contain the HTTP status code
    • Added ObjectFieldModel for fields that contain JSON content but do not represent a relation to another entity model
    • Added helper methods for comparing entity models
  • 12.55.8

    • Fixed various bugs related to entity generation
    • Fixed bug related to http session handling
    • HTTP proxy settings are now logged
  • 12.55.5

    • Added Entity Generation
    • Added Etag support. If the server resource has an etag then it is cached by the SDK for as long as the process is alive. The cache is destroyed once the process ends
    • All entity ids are now Strings. IDs are strings according to the metadata but there was some code that assumed IDs were integers
    • Entity collection now returns an OctaneCollection which is an extension of Collection. This includes important metadata about the returned collection:
      • The total count of entities (not including the current limit)
      • Whether the number of requested entities exceeds the total count of entities.
    • Added support for IN and BTW for queries
    • SDK extension moved, now part of the sdk repository,
    • SDK now uses SLF4J internally for all logging

    See the ALM Octane documentation for more information

Disclaimer

Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.

almoctanejavarestsdk's People

Contributors

alb-i986 avatar atoth91 avatar danfilip avatar dependabot[bot] avatar dima-hpe avatar elad-cohen-hpe avatar guetta14 avatar kdrtibor avatar laurabuzas avatar mrboba avatar naude-r avatar nissimshitrit avatar silviucanton99 avatar slbruce avatar surubariurazvan avatar tiutiumadalin avatar ttulme avatar tudordulau avatar xtrasonic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

almoctanejavarestsdk's Issues

DefectEntityModel getters throw ClassCastException on EmptyFieldModel

There's a bug in the sdk-generate-entity-models-maven-plugin.

Given a defect retrieved from the server with no owner set, DefectEntityModel#getOwner throws the following exception:

java.lang.ClassCastException: com.hpe.adm.nga.sdk.model.EmptyFieldModel cannot be cast to com.hpe.adm.nga.sdk.model.ReferenceFieldModel
  	at com.hpe.adm.nga.sdk.model.DefectEntityModel.getOwner(DefectEntityModel.java:1187)

Here is the implementation of the getOwner method, part of the class DefectEntityModel, which was generated by the maven plugin:

    public WorkspaceUserEntityModel getOwner(){
       final ReferenceFieldModel owner = (ReferenceFieldModel) wrappedEntityModel.getValue("owner");
		if (owner == null) {
            return null;
		}
		final EntityModel referenceFieldModel = owner.getValue();
                return new WorkspaceUserEntityModel(referenceFieldModel);
    }

The bug lies in the first line, which throws the ClassCastException above.

Instead of checking for null after the cast, it should check the type before attempting the cast:

if (wrappedEntityModel.getValue("owner") instanceof EmptyFieldModel) {
    return null;
}
final ReferenceFieldModel owner = (ReferenceFieldModel) wrappedEntityModel.getValue("owner");	

This applies to all the getters, I believe.

sdk-generate-entity-models-maven-plugin's generate goal fails due to NullPointerException

I've configured the latest version of the plugin and after running mvn clean install I get the following error:

Execution default of goal com.microfocus.adm.almoctane.sdk:sdk-generate-entity-models-maven-plugin:15.0.40.1:generate failed: Invocation of method 'getAllowedSuperTypesForReference' in class java.lang.Class threw exception java.lang.NullPointerException at /EntityModel.vm[line 82, column 50]

Debugging revealed that getAllowedSuperTypesForReference fails due to fieldTypedata.getTargets() returning null for a field with the following metadata:

FieldMetaData {
    name = "owner_import",
    entity_name = "attachment",
    field_type = "Reference",
    field_type_data.targets = null
    ...
}

Does the error have anything to do with an incorrectly setup ALM Octane instance or is it a generator issue?

Let me know if you need any more details (workspace fields full metadata, etc.) to reproduce the issue.

Full Error Stacktrace

λ mvn clean install -e
[INFO] --- sdk-generate-entity-models-maven-plugin:15.0.40.1:generate (default) @ octane-sdk-poc ---
[INFO] Starting to generate entities
[INFO] Building Octane context using Server: <hidden>
09:44:34,316 ERROR main root:164 - Exception in macro #getReference called at /EntityModel.vm[line 65, column 147]
09:44:34,317 ERROR main root:164 - Exception in macro #getter called at /EntityModel.vm[line 45, column 5]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.079 s
[INFO] Finished at: 2020-07-29T09:44:34+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.microfocus.adm.almoctane.sdk:sdk-generate-entity-models-maven-plugin:15.0.40.1:generate (default) on project octane-sdk-poc: Execution default of goal com.microfocus.adm.almoctane.sdk:sdk-generate-entity-models-maven-plugin:15.0.40.1:generate failed: Invocation of method 'getAllowedSuperTypesForReference' in  class java.lang.Class threw exception java.lang.NullPointerException at /EntityModel.vm[line 82, column 50] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.microfocus.adm.almoctane.sdk:sdk-generate-entity-models-maven-plugin:15.0.40.1:generate (default) on project octane-sdk-poc: Execution default of goal com.microfocus.adm.almoctane.sdk:sdk-generate-entity-models-maven-plugin:15.0.40.1:generate failed: Invocation of method 'getAllowedSuperTypesForReference' in  class java.lang.Class threw exception java.lang.NullPointerException at /EntityModel.vm[line 82, column 50]
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default of goal com.microfocus.adm.almoctane.sdk:sdk-generate-entity-models-maven-plugin:15.0.40.1:generate failed: Invocation of method 'getAllowedSuperTypesForReference' in  class java.lang.Class threw exception java.lang.NullPointerException at /EntityModel.vm[line 82, column 50]
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getAllowedSuperTypesForReference' in  class java.lang.Class threw exception java.lang.NullPointerException at /EntityModel.vm[line 82, column 50]
    at org.apache.velocity.runtime.parser.node.ASTMethod.handleInvocationException (ASTMethod.java:243)
    at org.apache.velocity.runtime.parser.node.ASTMethod.execute (ASTMethod.java:187)
    at org.apache.velocity.runtime.parser.node.ASTReference.execute (ASTReference.java:280)
    at org.apache.velocity.runtime.parser.node.ASTReference.value (ASTReference.java:567)
    at org.apache.velocity.runtime.parser.node.ASTExpression.value (ASTExpression.java:71)
    at org.apache.velocity.runtime.parser.node.ASTSetDirective.render (ASTSetDirective.java:142)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.VelocimacroProxy.render (VelocimacroProxy.java:216)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:311)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:230)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render (ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.parser.node.ASTElseIfStatement.render (ASTElseIfStatement.java:92)
    at org.apache.velocity.runtime.parser.node.ASTIfStatement.render (ASTIfStatement.java:106)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.VelocimacroProxy.render (VelocimacroProxy.java:216)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:311)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:230)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render (ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.Foreach.render (Foreach.java:420)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render (ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.SimpleNode.render (SimpleNode.java:342)
    at org.apache.velocity.Template.merge (Template.java:356)
    at org.apache.velocity.Template.merge (Template.java:260)
    at com.hpe.adm.nga.sdk.generate.GenerateModels.generateEntity (GenerateModels.java:276)
    at com.hpe.adm.nga.sdk.generate.GenerateModels.generate (GenerateModels.java:117)
    at com.hpe.adm.nga.sdk.generate.GenerateModelsPlugin.execute (GenerateModelsPlugin.java:47)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: java.lang.NullPointerException
    at com.hpe.adm.nga.sdk.generate.GeneratorHelper.getAllowedSuperTypesForReference (GeneratorHelper.java:207)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.doInvoke (UberspectImpl.java:395)
    at org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.invoke (UberspectImpl.java:384)
    at org.apache.velocity.runtime.parser.node.ASTMethod.execute (ASTMethod.java:173)
    at org.apache.velocity.runtime.parser.node.ASTReference.execute (ASTReference.java:280)
    at org.apache.velocity.runtime.parser.node.ASTReference.value (ASTReference.java:567)
    at org.apache.velocity.runtime.parser.node.ASTExpression.value (ASTExpression.java:71)
    at org.apache.velocity.runtime.parser.node.ASTSetDirective.render (ASTSetDirective.java:142)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.VelocimacroProxy.render (VelocimacroProxy.java:216)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:311)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:230)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render (ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.parser.node.ASTElseIfStatement.render (ASTElseIfStatement.java:92)
    at org.apache.velocity.runtime.parser.node.ASTIfStatement.render (ASTIfStatement.java:106)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.VelocimacroProxy.render (VelocimacroProxy.java:216)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:311)
    at org.apache.velocity.runtime.directive.RuntimeMacro.render (RuntimeMacro.java:230)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render (ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render (ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.Foreach.render (Foreach.java:420)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render (ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.SimpleNode.render (SimpleNode.java:342)
    at org.apache.velocity.Template.merge (Template.java:356)
    at org.apache.velocity.Template.merge (Template.java:260)
    at com.hpe.adm.nga.sdk.generate.GenerateModels.generateEntity (GenerateModels.java:276)
    at com.hpe.adm.nga.sdk.generate.GenerateModels.generate (GenerateModels.java:117)
    at com.hpe.adm.nga.sdk.generate.GenerateModelsPlugin.execute (GenerateModelsPlugin.java:47)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

Add support for expanding reference fields

Previously requests which included the "fields" query parameter were made with .../api/shared_spaces/<space_id>/workspaces/<workspace_id>/defects?fields=author,release,phase,priority,team. Octane used to return more information about reference fields, but this functionality was changed. Now it only returns enough information to identify the reference field without additional information. Octane also added a way to query extra fields for reference fields using the following format .../api/shared_spaces/<space_id>/workspaces/<workspace_id>/defects?fields=author{name},release,phase{name},priority,team and we also need to support this feature in the sdk

Possibility to have a shared HttpTransport

In the google documentation of HttpTransport it is mentioned that

For maximum efficiency, applications should use a single globally-shared instance of the HTTP transport.

GoogleHttpClient creates a new NetHttpTransport each time a new instance is created. According to the google documentation, this results in loss of efficiency. A solution for this would be to be able to give as a parameter an existing HttpTransport and use that in stead of creating a new NetHttpTransport each time.

SDK does not reauthenticate after cookie expires

After global session timeout expires the SDK does not authenticate and the next requests fail.

How it can be reproduced:

  • Set MINUTES_UNTIL_GLOBAL_SESSION_TIMEOUT site parameter to a low value (like 1 minute)
  • Make an Octane object and wait for the timeout to expire
  • Make another request after expiration and get an HttpResponseException: 401

Empty OctanePartialException

When an error triggers an OctanePartialException the system doesn't provide any feedback on what actually happened.

com.hpe.adm.nga.sdk.exception.OctanePartialException
	at com.hpe.adm.nga.sdk.network.google.GoogleHttpClient.wrapException(GoogleHttpClient.java:454)
	at com.hpe.adm.nga.sdk.network.google.GoogleHttpClient.executeRequest(GoogleHttpClient.java:410)
	at com.hpe.adm.nga.sdk.network.google.GoogleHttpClient.execute(GoogleHttpClient.java:336)
	at com.hpe.adm.nga.sdk.network.google.GoogleHttpClient.execute(GoogleHttpClient.java:319)
	at com.hpe.adm.nga.sdk.network.OctaneRequest.getEntitiesResponse(OctaneRequest.java:81)
	at com.hpe.adm.nga.sdk.entities.create.CreateHelper.createEntities(CreateHelper.java:56)
	at com.hpe.adm.nga.sdk.entities.create.CreateTypedEntities.execute(CreateTypedEntities.java:52)
	at com.example.octane.OctaneClient.createDefects(OctaneClient.java:28)
	at com.example.octane.OctaneClientTest.createDefectAndRetrieve(OctaneClientTest.java:48)

I analysed the code, and the problem is that you are not setting message in the super class.

public class OctanePartialException extends RuntimeException{

	private Collection<EntityModel> entities = null;
	private Collection<ErrorModel> errors = null;
	
	/**
	 * Creates a new OctanePartialException object based on errors and entities models
	 * 
	 * @param errorModels - error models
	 * @param entities - entities models  
	 */
	public OctanePartialException(Collection<ErrorModel> errorModels, Collection<EntityModel> entities){
		
		setEntitiesModels(entities);
		setErrorModels(errorModels);
		
	}

For example, you could be calling super("my custom error message") in the constructor.

EntityModel toString

EntityModel does not have a toString method which means that when we want to log an instance of EntityModel, it has to be first parsed with ModelParser.getInstance().getEntitiesJSONObject(entityModel).toString());. Since there is a way to turn an entity model to a string, it would be easier to log entity models if there was a toString in the actual EntityModel class.

Universal code formatting rules

I've worked on this code from 2 IDE's and 3 computers. It's a bit of a pain to see inconsistent formatting in all the diffs.

I would like to improve it, but I'm not sure how.
Is there any universal code formatter we can use, something that works consistently with both IntelliJ and Eclipse.
Or adding some formatter as a pre-commit hook?

@slbruce Any ideas?

Requests with null value fields

JSONObject, which is used to create the payload of the request, does not put fields in the payload if they have the value (java) null. If we want to add a field with the value null, it has to have the value "JSONObject.NULL" (see the json object documentation)

There are two ways we can handle this:

  1. Create a NullFieldModel class which gets a name and always returns the value JSONObject.NULL. When the user wants to set a field with a null value, it will create a new instance of this class and set it in the entity model.

  2. Treat all null values as JSONObject.NULL. This might have a backwards compatibility impact since now some fields which were previously ignored, will be added to the request and will have the value null.

I personally think that the first option is better.

Bad code generated

the entity model generation results in bad code.

as an example consider:
public enum StoryPhase { CANCELLED("vkp470o591rlqt56k8ve47j65") , SUSPENDED("p15q36190oj4ycowodry67ozg") , DONE("phase.story.done") , NEW("phase.story.new") , IN_TESTING/IN_REVIEW("phase.story.intesting") , IN_PROGRESS("phase.story.inprogress");

in above IN_TESTING/IN_REVIEW is not a valid identifier. would it be possible to cater for this?

Invalid enum names

in some cases an admin can choose a name that results in invalid java identifiers, e.g. SHELF-READY.

would it make sense to impose limitations on the octane back-end during creation of names?

temporary fix in PR #143

Handle entities with id of type long or no id.

As of 16.0.100 in Octane there are entities with:

  • id of type long:
    • run_history
    • log_line
    • model_path
    • agent
    • autocomplete_step
  • no id:
    • audit_action

When generating EntityModels, those entities and the future ones added in Octane will throw an exception when compiling the classes.

Logging can cause OOM issues

java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3664) ~[?:1.8.0_192]
at java.lang.String.(String.java:207) ~[?:1.8.0_192]
at java.lang.StringBuilder.toString(StringBuilder.java:407) ~[?:1.8.0_192]
at java.util.Formatter.toString(Formatter.java:2355) ~[?:1.8.0_192]
at java.lang.String.format(String.java:2940) ~[?:1.8.0_192]
at com.hpe.adm.nga.sdk.network.OctaneRequest.getEntitiesResponse(OctaneRequest.java:68) ~[?:?]
at com.hpe.adm.nga.sdk.entities.get.GetHelper.getEntityModels(GetHelper.java:41) ~[?:?]
at com.hpe.adm.nga.sdk.entities.get.GetEntities.execute(GetEntities.java:40) ~[?:?]

Support Java 9

Tests fail in Java 9.

org.objenesis.ObjenesisException: java.lang.reflect.InvocationTargetException Caused by: java.lang.reflect.InvocationTargetException Caused by: java.lang.IllegalAccessError: class jdk.internal.reflect.ConstructorAccessorImpl loaded by org/powermock/core/classloader/MockClassLoader cannot access jdk/internal/reflect superclass jdk.internal.reflect.MagicAccessorImpl

It seems that Mockito and PowerMock need to be updated to support Java 9

Unable to generate entity resources

I was trying to generate entities when started encountering this issue. Please help

[INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 17.474 s [INFO] Finished at: 2020-01-17T10:40:36+05:30 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:3.1.1:javadoc (default-cli) on project projectDir: An error has occurred in Javadoc report generation: [ERROR] Exit code: 1 - C:\Users\user\eclipse-workspace\projectDir\target\generated-sources\com\hpe\adm\nga\sdk\model\FeatureEntityModel.java:330: error: unmappable character for encoding UTF-8 [ERROR] * Description: Total number of a feature?s descendants (user stories/defects/quality stories) that have vulnerabilities which are significant and not closed.

In the genrated files, in the mentioned line 330 there is an unidentifiable character in UTF-8
image

This is happening for 24 files. Kindly help

Set read (and connection) timeout

Currently the GoogleHttpClient has a hard-coded read timeout of 60000 (1 minute). Sometimes it might take more than that to receive an answer from Octane when making some requests (e.g. updating 500 entities in bulk). The result is a socket timeout exception even if the request actually finish without a problem in 61 seconds.
It would be nice to be able to create a GoogleHttpClient with a custom read timeout. While at it, it might be a good idea to add support for connection timeout as well. Although I did not personally encounter any problem with this yet, the workaround for increasing the read timeout also included the connection timeout used to establish a connection. By default (in HttpRequest from google) it is 20 seconds.
The current workaround is extending the GoogleHttpClient and creating a new NetHttpTransport and request factory:

public class TimeoutGoogleHttpClient extends GoogleHttpClient {
    public TimeoutGoogleHttpClient (String urlDomain, int readTimeout, int connectionTimeout) {
        super(urlDomain);

        HttpRequestInitializer requestInitializer = (request) -> {
            super.requestInitializer.initialize(request);
            request.setReadTimeout(readTimeout);
            request.setConnectTimeout(connectionTimeout);
        };

        this.requestFactory =  new NetHttpTransport().createRequestFactory(requestInitializer);
    }
}

Add ability to use a header for a single request

Once an octane object is created with or without a header, there isn't a way to use the same object to make a request with a different header. To make the request, a new octane object would need to be made with a different header and the same credentials. It would be nice if the requests could be made with the same octane object.

E.G.
An octane object was created without a header. A get request needs to be made with the tech preview header and a put request needs to be made using a legacy header. Instead of creating 3 different octane objects, have the 2 requests be made with the original octane object and a custom header:
octane.entityList(...).get().withHeader("ALM-OCTANE-TECH-PREVIEW","true").execute()
and
octane.entityList(...).update().withHeader("LegacyHeaderName","LegacyHeaderValue").entities(...).execute()
or give a map with headers which completely replaces the old ones for the current request.

Pull change_set data from audit and history_logs entities

Is there a way to get the "change_set" information for entity types "audit" or "history_logs"?
When I create the entity model collection for those types I don't see that field using the getValues method.

Sample code:

Collection<EntityModel> histlogs = octane.entityList("history_logs").get().execute();
		Iterator<EntityModel> i = histlogs.iterator();
		Collection<FieldModel> histlogfields = i.next().getValues();
		histlogfields.forEach(histlogfield -> logger.info( histlogfield.getName()));

Output:

20-01-21 18:08:06:172  INFO main sdk.Octane:278 - Building Octane context using Server: http://192.168.0.100:8080 SharedSpace: 1001 Workspace: 1003
20-01-21 18:08:11:318  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - user_id
20-01-21 18:08:11:318  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - workspace_id
20-01-21 18:08:11:318  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - entity_type
20-01-21 18:08:11:319  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - action
20-01-21 18:08:11:320  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - entity_physical_id
20-01-21 18:08:11:321  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - user_name
20-01-21 18:08:11:321  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - session_id
20-01-21 18:08:11:321  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - entity_id
20-01-21 18:08:11:321  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - timestamp
20-01-21 18:08:11:321  INFO main ALM_Octane_Metrics.DummyOctaneHttpClientExample:174 - type

list_node names not sent when using java sdk

When using the normal rest sdk via browser (and the javascript client as well), additional information about list_nodes like the dispaly name is sent. When using the java REST SDK that's not the case.

Example: If I request a test_manual with the browser, I get something like this (phase is a placeholder for any list_node):

...
phase: {
    type: "phase",
    activity_level: 0,
    logical_name: "phase.test_manual.ready",
    name: "Ready", //this is the value I am interested in
    index: 600,
    id: "phase.test_manual.ready"
}
...

If I execute the same request with the java sdk I only get

...
phase:{
    "type":"phase",
    "id":"phase.test_manual.ready" //this is what I get from the java client
}
...

We have many user defined fields and are mostly interested in the name attributes not their technical ids. For now we load all list_node values and map the ids to their names but this is not very scalable if the number of possible user defined fields and values goes up.

I did some debugging already and the only thing that makes a difference is the session cookie. If I use the cookie from the java sdk in the browser I get the same result with only type and id.

Is there a special treatment for the java rest client inside octane?

String.getBytes without charset

I work on MFConnect which uses the Octane SDK to create attachments.
I think there is a bug in the class GoogleHttpClient (or maybe there is a workaround that I don’t know about).

The code highlighted in yellow below looked like this before my change: octaneHttpRequest.getContent().getBytes()
There is no charset specified when converting the “content” into bytes.
We have at least one customer where the default charset is not UTF-8 which results in a failure to create an attachment.

/**
 * Generates HTTP content based on input parameters and stream.
 *
 * @param octaneHttpRequest - JSON entity model.
 * @return - Generated HTTP content.
 */
private MultipartContent generateMultiPartContent(OctaneHttpRequest.PostBinaryOctaneHttpRequest octaneHttpRequest) {
    // Add parameters
    MultipartContent content = new MultipartContent()
            .setMediaType(new HttpMediaType(HTTP_MEDIA_TYPE_MULTIPART_NAME)
                    .setParameter(HTTP_MULTIPART_BOUNDARY_NAME, HTTP_MULTIPART_BOUNDARY_VALUE));

    ByteArrayContent byteArrayContent;
                          try {
                                         byteArrayContent = new ByteArrayContent("application/json", octaneHttpRequest.getContent().getBytes("UTF-8"));
                          } catch (UnsupportedEncodingException e) {
                                         logger.error(e.getMessage(), e);
                                         throw new IllegalArgumentException("content can't be converted to UTF-8: " + octaneHttpRequest.getContent(), e);
                          }
    MultipartContent.Part part1 = new MultipartContent.Part(byteArrayContent);

Can you let me know if you agree with this change, or if there is a way I can work around this problem.

The HPSoftware organisation is being deprecated!

The HPSoftware organisation is being deprecated and all active repositories should be moved to the [https://github.com/MicroFocus](Micro Focus) organisation.

After the 31st December 2017 this organisation and all its repositories will be locked and the HPSoftware organisation will be deleted.

For any questions please contact me or comment on this issue

Getting Shared space data

When trying to get shared space data, the builder will create an invalid URI using the format "/api/siteadmin/"which I believe is not being used, so when I run it I get a 404 error.

sdk-generate-entity-models-maven-plugin breaks if list_node names are not valid java identifiers

When using the maven-plugin to generate all typed entities, non-compilable classes are generated.

Our customer has many list_nodes with names that start with a number or use spaces.
Those names are used to generate the list_node enums in Lists.java which fails.
Because of this most of the generated Mdoels are also invalid because the placeholders are not replaced rsulting in code like this:

public java.util.Collection<com.hpe.adm.nga.sdk.enums.Lists.${listName}> getMyTypeUdf() {
    final MultiReferenceFieldModel my_type_udf = (MultiReferenceFieldModel) wrappedEntityModel.getValue("my_type_udf");
    if (my_type_udf == null) {
        return java.util.Collections.emptyList();
    }
	final java.util.Collection<EntityModel> value =my_type_udf.getValue();
	return value.stream().map(com.hpe.adm.nga.sdk.enums.Lists.${listName}::getFromEntityModel)
	    .collect(java.util.stream.Collectors.toList());
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.