5858import com .microfocus .application .automation .tools .octane .model .processors .projects .AbstractProjectProcessor ;
5959import com .microfocus .application .automation .tools .octane .model .processors .projects .JobProcessorFactory ;
6060import com .microfocus .application .automation .tools .octane .tests .TestListener ;
61+ import com .microfocus .application .automation .tools .octane .tests .junit .JUnitExtension ;
6162import hudson .ProxyConfiguration ;
6263import hudson .console .PlainTextConsoleOutputStream ;
64+ import hudson .matrix .MatrixConfiguration ;
6365import hudson .model .*;
6466import hudson .security .ACLContext ;
6567import jenkins .model .Jenkins ;
7577import java .io .*;
7678import java .net .URL ;
7779import java .net .URLDecoder ;
80+ import java .nio .charset .StandardCharsets ;
81+ import java .nio .file .Files ;
7882import java .util .*;
7983import java .util .function .BiConsumer ;
8084import java .util .function .Function ;
@@ -111,13 +115,13 @@ public void suspendCIEvents(boolean suspend) {
111115
112116 @ Override
113117 public File getAllowedOctaneStorage () {
114- return new File (Jenkins .getInstance ().getRootDir (), "userContent" );
118+ return new File (Jenkins .get ().getRootDir (), "userContent" );
115119 }
116120
117121 @ Override
118122 public CIProxyConfiguration getProxyConfiguration (URL targetUrl ) {
119123 CIProxyConfiguration result = null ;
120- ProxyConfiguration proxy = Jenkins .getInstance ().proxy ;
124+ ProxyConfiguration proxy = Jenkins .get ().proxy ;
121125 if (proxy != null ) {
122126 boolean noProxyHost = false ;
123127 for (Pattern pattern : proxy .getNoProxyHostPatterns ()) {
@@ -141,66 +145,50 @@ public CIProxyConfiguration getProxyConfiguration(URL targetUrl) {
141145 public CIJobsList getJobsList (boolean includeParameters ) {
142146 ACLContext securityContext = startImpersonation ();
143147 CIJobsList result = dtoFactory .newDTO (CIJobsList .class );
144- PipelineNode tmpConfig ;
145- TopLevelItem tmpItem ;
146- List <PipelineNode > list = new ArrayList <>();
148+ Map <String , PipelineNode > jobsMap = new HashMap <>();
149+
147150 try {
148- boolean hasReadPermission = Jenkins .getInstance ().hasPermission (Item .READ );
151+ boolean hasReadPermission = Jenkins .get ().hasPermission (Item .READ );
149152 if (!hasReadPermission ) {
150- stopImpersonation (securityContext );
151153 throw new PermissionException (403 );
152154 }
153- List <String > itemNames = (List <String >) Jenkins .getInstance ().getTopLevelItemNames ();
154- for (String name : itemNames ) {
155- tmpItem = Jenkins .getInstance ().getItem (name );
156-
157- if (tmpItem == null ) {
158- continue ;
159- }
160155
161- String jobName = tmpItem .getName ();
162- String jobClassName = tmpItem .getClass ().getName ();
156+ Collection <String > jobNames = Jenkins .get ().getJobNames ();
157+ for (String jobName : jobNames ) {
158+ String tempJobName = jobName ;
163159 try {
164- if (tmpItem instanceof AbstractProject ) {
165- AbstractProject abstractProject = (AbstractProject ) tmpItem ;
166- if (abstractProject .isDisabled ()) {
167- continue ;
168- }
169- tmpConfig = createPipelineNode (name , abstractProject , includeParameters );
170- list .add (tmpConfig );
171- } else if (jobClassName .equals (JobProcessorFactory .WORKFLOW_JOB_NAME )) {
172- tmpConfig = createPipelineNode (name , (Job ) tmpItem , includeParameters );
173- list .add (tmpConfig );
174- } else if (jobClassName .equals (JobProcessorFactory .FOLDER_JOB_NAME )) {
175- for (Job tmpJob : tmpItem .getAllJobs ()) {
176- jobName = tmpJob .getFullName ();
177- tmpConfig = createPipelineNode (jobName , tmpJob , includeParameters );
178- list .add (tmpConfig );
179- }
180- } else if (jobClassName .equals (JobProcessorFactory .WORKFLOW_MULTI_BRANCH_JOB_NAME )) {
181- tmpConfig = createPipelineNodeFromJobName (name );
182- list .add (tmpConfig );
183- } else if (jobClassName .equals (JobProcessorFactory .GITHUB_ORGANIZATION_FOLDER )) {
184- Collection <? extends Item > items = ((AbstractFolder ) tmpItem ).getItems ();
185- for (Item item : items ) {
186- jobName = item .getFullName ();
187- tmpConfig = createPipelineNodeFromJobNameAndFolder (item .getDisplayName (), name );
188- list .add (tmpConfig );
189- }
160+ Job tmpJob = (Job ) Jenkins .get ().getItemByFullName (tempJobName );
161+
162+ if (tmpJob == null ) {
163+ continue ;
164+ }
165+ if (tmpJob instanceof AbstractProject && ((AbstractProject ) tmpJob ).isDisabled ()) {
166+ continue ;
167+ }
168+ if (tmpJob instanceof MatrixConfiguration ) {
169+ continue ;
170+ }
171+
172+ PipelineNode tmpConfig ;
173+ if (JobProcessorFactory .WORKFLOW_MULTI_BRANCH_JOB_NAME .equals (tmpJob .getParent ().getClass ().getName ())) {
174+ tempJobName = tmpJob .getParent ().getFullName ();
175+ tmpConfig = createPipelineNodeFromJobName (tempJobName );
190176 } else {
191- logger . info ( String . format ( "getJobsList : Item '%s' of type '%s' is not supported" , jobName , jobClassName ) );
177+ tmpConfig = createPipelineNode ( tempJobName , tmpJob , includeParameters );
192178 }
179+ jobsMap .put (tempJobName , tmpConfig );
193180 } catch (Throwable e ) {
194- logger .error ("getJobsList : Failed to add job '" + jobName + "' to JobList : " + e . getClass (). getCanonicalName () + " - " + e . getMessage () , e );
181+ logger .error ("failed to add job '" + tempJobName + "' to JobList" , e );
195182 }
196-
197183 }
198- result .setJobs (list .toArray (new PipelineNode [0 ]));
199- } catch (AccessDeniedException e ) {
184+
185+ result .setJobs (jobsMap .values ().toArray (new PipelineNode [0 ]));
186+ } catch (AccessDeniedException ade ) {
200187 throw new PermissionException (403 );
201188 } finally {
202189 stopImpersonation (securityContext );
203190 }
191+
204192 return result ;
205193 }
206194
@@ -209,7 +197,7 @@ public PipelineNode getPipeline(String rootJobCiId) {
209197 ACLContext securityContext = startImpersonation ();
210198 try {
211199 PipelineNode result ;
212- boolean hasRead = Jenkins .getInstance ().hasPermission (Item .READ );
200+ boolean hasRead = Jenkins .get ().hasPermission (Item .READ );
213201 if (!hasRead ) {
214202 throw new PermissionException (403 );
215203 }
@@ -340,6 +328,7 @@ public InputStream getTestsResult(String jobId, String buildId) {
340328 } catch (Exception fnfe ) {
341329 logger .error ("'" + TestListener .TEST_RESULT_FILE + "' file no longer exists, test results of '" + jobId + " #" + buildId + "' won't be pushed to Octane" , fnfe );
342330 }
331+ tryRemoveTempTestResultFile (run );
343332 } else {
344333 logger .error ("build '" + jobId + " #" + buildId + "' not found" );
345334 }
@@ -349,6 +338,23 @@ public InputStream getTestsResult(String jobId, String buildId) {
349338 }
350339 }
351340
341+ private void tryRemoveTempTestResultFile (Run run ) {
342+ try {
343+ File [] matches = run .getRootDir ().listFiles ((dir , name ) -> name .startsWith (JUnitExtension .TEMP_TEST_RESULTS_FILE_NAME_PREFIX ));
344+ if (matches != null ) {
345+ for (File f : matches ) {
346+ try {
347+ Files .deleteIfExists (f .toPath ());
348+ } catch (Exception e ) {
349+ logger .error ("Failed to delete the temp test result file at '" + f .getPath () + "'" , e );
350+ }
351+ }
352+ }
353+ } catch (Exception e ) {
354+ logger .error ("Fail to tryRemoveTempTestResultFile : " + e .getMessage ());
355+ }
356+ }
357+
352358 @ Override
353359 public InputStream getBuildLog (String jobId , String buildId ) {
354360 ACLContext originalContext = startImpersonation ();
@@ -415,12 +421,13 @@ public SSCProjectConfiguration getSSCProjectConfiguration(String jobId, String b
415421 stopImpersonation (originalContext );
416422 }
417423 }
424+
418425 @ Override
419426 public Long getFodRelease (String jobId , String buildId ) {
420427 ACLContext originalContext = startImpersonation ();
421428 try {
422429 Run run = getRunByRefNames (jobId , buildId );
423- if (run != null && run instanceof AbstractBuild ) {
430+ if (run instanceof AbstractBuild ) {
424431 return FodConfigUtil .getFODReleaseFromBuild ((AbstractBuild ) run );
425432 } else {
426433 logger .error ("build '" + jobId + " #" + buildId + "' (of specific type AbstractBuild) not found" );
@@ -431,7 +438,7 @@ public Long getFodRelease(String jobId, String buildId) {
431438 }
432439 }
433440
434- @ Override
441+ @ Override
435442 public FodServerConfiguration getFodServerConfiguration () {
436443
437444 ACLContext originalContext = startImpersonation ();
@@ -450,6 +457,7 @@ public FodServerConfiguration getFodServerConfiguration() {
450457 stopImpersonation (originalContext );
451458 }
452459 }
460+
453461 @ Override
454462 public void runTestDiscovery (DiscoveryInfo discoveryInfo ) {
455463 ACLContext securityContext = startImpersonation ();
@@ -466,8 +474,7 @@ public PipelineNode createExecutor(DiscoveryInfo discoveryInfo) {
466474 ACLContext securityContext = startImpersonation ();
467475 try {
468476 Job project = TestExecutionJobCreatorService .createExecutor (discoveryInfo );
469- PipelineNode result = ModelFactory .createStructureItem (project );
470- return result ;
477+ return ModelFactory .createStructureItem (project );
471478 } finally {
472479 stopImpersonation (securityContext );
473480 }
@@ -480,8 +487,7 @@ public PipelineNode createExecutor(DiscoveryInfo discoveryInfo) {
480487 private Job createExecutorByJobName (String uftExecutorJobNameWithTestRunner ) {
481488 ACLContext securityContext = startImpersonation ();
482489 try {
483- Job project = TestExecutionJobCreatorService .createExecutorByJobName (uftExecutorJobNameWithTestRunner );
484- return project ;
490+ return TestExecutionJobCreatorService .createExecutorByJobName (uftExecutorJobNameWithTestRunner );
485491 } catch (Exception e ) {
486492 logger .warn ("Failed to create createExecutor by name : " + e .getMessage ());
487493 return null ;
@@ -541,7 +547,7 @@ private void stopImpersonation(ACLContext impersonatedContext) {
541547
542548 private PipelineNode createPipelineNode (String name , Job job , boolean includeParameters ) {
543549 PipelineNode tmpConfig = dtoFactory .newDTO (PipelineNode .class )
544- .setJobCiId (JobProcessorFactory .getFlowProcessor (job ).getTranslateJobName ())
550+ .setJobCiId (JobProcessorFactory .getFlowProcessor (job ).getTranslatedJobName ())
545551 .setName (name );
546552 if (includeParameters ) {
547553 tmpConfig .setParameters (ParameterProcessors .getConfigs (job ));
@@ -555,20 +561,14 @@ private PipelineNode createPipelineNodeFromJobName(String name) {
555561 .setName (name );
556562 }
557563
558- private PipelineNode createPipelineNodeFromJobNameAndFolder (String name , String folderName ) {
559- return dtoFactory .newDTO (PipelineNode .class )
560- .setJobCiId (folderName + "/" + name )
561- .setName (folderName + "/" + name );
562- }
563-
564564 private InputStream getOctaneLogFile (Run run ) {
565565 InputStream result = null ;
566566 String octaneLogFilePath = run .getLogFile ().getParent () + File .separator + "octane_log" ;
567567 File logFile = new File (octaneLogFilePath );
568568 if (!logFile .exists ()) {
569569 try (FileOutputStream fileOutputStream = new FileOutputStream (logFile );
570- InputStream logStream = run .getLogInputStream ();
571- PlainTextConsoleOutputStream out = new PlainTextConsoleOutputStream (fileOutputStream )) {
570+ InputStream logStream = run .getLogInputStream ();
571+ PlainTextConsoleOutputStream out = new PlainTextConsoleOutputStream (fileOutputStream )) {
572572 IOUtils .copy (logStream , out );
573573 out .flush ();
574574 } catch (IOException ioe ) {
@@ -639,8 +639,6 @@ private List<ParameterValue> createParameters(Job project, CIParameters ciParame
639639 }
640640 break ;
641641 case NUMBER :
642- tmpValue = new StringParameterValue (ciParameter .getName (), ciParameter .getValue ().toString ());
643- break ;
644642 case STRING :
645643 tmpValue = new StringParameterValue (ciParameter .getName (), ciParameter .getValue ().toString ());
646644 break ;
@@ -688,7 +686,7 @@ private Job getJobByRefId(String jobRefId) {
688686 Job result = null ;
689687 if (jobRefId != null ) {
690688 try {
691- jobRefId = URLDecoder .decode (jobRefId , "UTF-8" );
689+ jobRefId = URLDecoder .decode (jobRefId , StandardCharsets . UTF_8 . name () );
692690 TopLevelItem item = getTopLevelItem (jobRefId );
693691 if (item instanceof Job ) {
694692 result = (Job ) item ;
@@ -713,34 +711,59 @@ private Job getJobByRefId(String jobRefId) {
713711 }
714712
715713 private Item getItemByRefId (String itemRefId ) {
716- Item result = null ;
717- if (itemRefId != null ) {
718- try {
719- String itemRefIdUncoded = URLDecoder .decode (itemRefId , "UTF-8" );
720- if (itemRefIdUncoded .contains ("/" )) {
721- String newItemRefId = itemRefIdUncoded .substring (0 , itemRefIdUncoded .indexOf ("/" ));
722- Item item = getTopLevelItem (newItemRefId );
723- if (item != null && item .getClass ().getName ().equals (JobProcessorFactory .GITHUB_ORGANIZATION_FOLDER )) {
724- Collection <? extends Item > allItems = ((AbstractFolder ) item ).getItems ();
725- for (Item multibranchItem : allItems ) {
726- if (itemRefIdUncoded .endsWith (multibranchItem .getName ())) {
727- result = multibranchItem ;
728- break ;
729- }
714+ if (itemRefId == null ) {
715+ return null ;
716+ }
717+
718+ try {
719+ String itemRefIdDecoded = URLDecoder .decode (itemRefId , StandardCharsets .UTF_8 .name ());
720+ if (!itemRefIdDecoded .contains ("/" )) {
721+ return null ;
722+ }
723+
724+ String newItemRefId = itemRefIdDecoded .substring (0 , itemRefIdDecoded .indexOf ('/' ));
725+ Item item = getTopLevelItem (newItemRefId );
726+ if (item == null ) {
727+ return null ;
728+ }
729+
730+ Item result = null ;
731+ if (item .getClass ().getName ().equals (JobProcessorFactory .GITHUB_ORGANIZATION_FOLDER )) {
732+ Collection <? extends Item > allItems = ((AbstractFolder ) item ).getItems ();
733+ for (Item multiBranchItem : allItems ) {
734+ if (itemRefIdDecoded .endsWith (multiBranchItem .getName ())) {
735+ result = multiBranchItem ;
736+ break ;
737+ }
738+ }
739+ } else {
740+ Collection <? extends Job > allJobs = item .getAllJobs ();
741+ for (Job job : allJobs ) {
742+ if (JobProcessorFactory .WORKFLOW_MULTI_BRANCH_JOB_NAME .equals (job .getParent ().getClass ().getName ()) &&
743+ itemRefId .endsWith (job .getParent ().getFullName ())
744+ ) {
745+ result = (Item ) job .getParent ();
746+ } else {
747+ if (itemRefId .endsWith (job .getName ())) {
748+ result = job ;
730749 }
731750 }
751+ if (result != null ) {
752+ break ;
753+ }
732754 }
733- } catch (UnsupportedEncodingException uee ) {
734- logger .error ("failed to decode job ref ID '" + itemRefId + "'" , uee );
735755 }
756+ return result ;
757+ } catch (UnsupportedEncodingException uee ) {
758+ logger .error ("failed to decode job ref ID '" + itemRefId + "'" , uee );
759+ return null ;
736760 }
737- return result ;
738761 }
739762
740763 private TopLevelItem getTopLevelItem (String jobRefId ) {
741764 TopLevelItem item ;
742765 try {
743- item = Jenkins .getInstance ().getItem (jobRefId );
766+ item = Jenkins .get ().getItem (jobRefId );
744767 } catch (AccessDeniedException e ) {
745768 String user = ConfigurationService .getSettings (getInstanceId ()).getImpersonatedUser ();
746769 if (user != null && !user .isEmpty ()) {
@@ -754,7 +777,7 @@ private TopLevelItem getTopLevelItem(String jobRefId) {
754777
755778 public static CIServerInfo getJenkinsServerInfo () {
756779 CIServerInfo result = dtoFactory .newDTO (CIServerInfo .class );
757- String serverUrl = Jenkins .getInstance ().getRootUrl ();
780+ String serverUrl = Jenkins .get ().getRootUrl ();
758781 if (serverUrl != null && serverUrl .endsWith ("/" )) {
759782 serverUrl = serverUrl .substring (0 , serverUrl .length () - 1 );
760783 }
0 commit comments