You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jg...@apache.org on 2022/03/10 12:52:27 UTC
[nifi] branch main updated: NIFI-9775 Create RuntimeManifestService
This is an automated email from the ASF dual-hosted git repository.
jgresock pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 546f986 NIFI-9775 Create RuntimeManifestService
546f986 is described below
commit 546f986603458062d9676b8511f8e566d0748f26
Author: Bryan Bende <bb...@gmail.com>
AuthorDate: Tue Mar 8 11:13:44 2022 -0500
NIFI-9775 Create RuntimeManifestService
Signed-off-by: Joe Gresock <jg...@gmail.com>
This closes #5849.
---
.../nifi/manifest/RuntimeManifestService.java | 31 +++++
.../manifest/StandardRuntimeManifestService.java | 111 ++++++++++++++++++
.../src/main/resources/nifi-context.xml | 9 ++
.../StandardRuntimeManifestServiceTest.java | 125 +++++++++++++++++++++
.../META-INF/docs/extension-manifest.xml | 19 ++++
.../META-INF/docs/extension-manifest.xml | 87 ++++++++++++++
.../nifi/web/controller/ControllerFacade.java | 69 +-----------
.../src/main/resources/nifi-web-api-context.xml | 3 +-
8 files changed, 388 insertions(+), 66 deletions(-)
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/manifest/RuntimeManifestService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/manifest/RuntimeManifestService.java
new file mode 100644
index 0000000..7f02125
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/manifest/RuntimeManifestService.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.manifest;
+
+import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
+
+/**
+ * Produces a RuntimeManifest for the current NiFi instance.
+ */
+public interface RuntimeManifestService {
+
+ /**
+ * @return the RuntimeManifest
+ */
+ RuntimeManifest getManifest();
+
+}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/manifest/StandardRuntimeManifestService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/manifest/StandardRuntimeManifestService.java
new file mode 100644
index 0000000..74473a2
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/manifest/StandardRuntimeManifestService.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.manifest;
+
+import org.apache.nifi.bundle.Bundle;
+import org.apache.nifi.bundle.BundleDetails;
+import org.apache.nifi.c2.protocol.component.api.BuildInfo;
+import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
+import org.apache.nifi.extension.manifest.ExtensionManifest;
+import org.apache.nifi.extension.manifest.parser.ExtensionManifestParser;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.nar.NarClassLoadersHolder;
+import org.apache.nifi.runtime.manifest.RuntimeManifestBuilder;
+import org.apache.nifi.runtime.manifest.impl.SchedulingDefaultsFactory;
+import org.apache.nifi.runtime.manifest.impl.StandardRuntimeManifestBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Optional;
+import java.util.Set;
+
+public class StandardRuntimeManifestService implements RuntimeManifestService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(StandardRuntimeManifestService.class);
+
+ private static final String RUNTIME_MANIFEST_IDENTIFIER = "nifi";
+ private static final String RUNTIME_TYPE = "nifi";
+
+ private final ExtensionManager extensionManager;
+ private final ExtensionManifestParser extensionManifestParser;
+
+ public StandardRuntimeManifestService(final ExtensionManager extensionManager, final ExtensionManifestParser extensionManifestParser) {
+ this.extensionManager = extensionManager;
+ this.extensionManifestParser = extensionManifestParser;
+ }
+
+ @Override
+ public RuntimeManifest getManifest() {
+ final Set<Bundle> allBundles = extensionManager.getAllBundles();
+
+ final Bundle frameworkBundle = getFrameworkBundle();
+ final BundleDetails frameworkDetails = frameworkBundle.getBundleDetails();
+ final Date frameworkBuildDate = frameworkDetails.getBuildTimestampDate();
+
+ final BuildInfo buildInfo = new BuildInfo();
+ buildInfo.setVersion(frameworkDetails.getCoordinate().getVersion());
+ buildInfo.setRevision(frameworkDetails.getBuildRevision());
+ buildInfo.setCompiler(frameworkDetails.getBuildJdk());
+ buildInfo.setTimestamp(frameworkBuildDate == null ? null : frameworkBuildDate.getTime());
+
+ final RuntimeManifestBuilder manifestBuilder = new StandardRuntimeManifestBuilder()
+ .identifier(RUNTIME_MANIFEST_IDENTIFIER)
+ .runtimeType(RUNTIME_TYPE)
+ .version(buildInfo.getVersion())
+ .schedulingDefaults(SchedulingDefaultsFactory.getNifiSchedulingDefaults())
+ .buildInfo(buildInfo);
+
+ for (final Bundle bundle : allBundles) {
+ getExtensionManifest(bundle).ifPresent(em -> manifestBuilder.addBundle(em));
+ }
+
+ return manifestBuilder.build();
+ }
+
+ private Optional<ExtensionManifest> getExtensionManifest(final Bundle bundle) {
+ final BundleDetails bundleDetails = bundle.getBundleDetails();
+ final File manifestFile = new File(bundleDetails.getWorkingDirectory(), "META-INF/docs/extension-manifest.xml");
+ if (!manifestFile.exists()) {
+ LOGGER.warn("Unable to find extension manifest for [{}] at [{}]...", bundleDetails.getCoordinate(), manifestFile.getAbsolutePath());
+ return Optional.empty();
+ }
+
+ try (final InputStream inputStream = new FileInputStream(manifestFile)) {
+ final ExtensionManifest extensionManifest = extensionManifestParser.parse(inputStream);
+ // Newer NARs will have these fields populated in extension-manifest.xml, but older NARs will not, so we can
+ // set the values from the BundleCoordinate which already has the group, artifact id, and version
+ extensionManifest.setGroupId(bundleDetails.getCoordinate().getGroup());
+ extensionManifest.setArtifactId(bundleDetails.getCoordinate().getId());
+ extensionManifest.setVersion(bundleDetails.getCoordinate().getVersion());
+ return Optional.of(extensionManifest);
+ } catch (final IOException e) {
+ LOGGER.error("Unable to load extension manifest for bundle [{}]", bundleDetails.getCoordinate(), e);
+ return Optional.empty();
+ }
+ }
+
+ // Visible for overriding from tests
+ Bundle getFrameworkBundle() {
+ return NarClassLoadersHolder.getInstance().getFrameworkBundle();
+ }
+
+}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/resources/nifi-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/resources/nifi-context.xml
index 040329b..fe8058e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/resources/nifi-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/resources/nifi-context.xml
@@ -67,6 +67,15 @@
<property name="authorizer" ref="authorizer" />
</bean>
+ <!-- extension manifest parser -->
+ <bean id="extensionManifestParser" class="org.apache.nifi.extension.manifest.parser.jaxb.JAXBExtensionManifestParser" />
+
+ <!-- runtime manifest generator -->
+ <bean id="runtimeManifestService" class="org.apache.nifi.manifest.StandardRuntimeManifestService" >
+ <constructor-arg ref="extensionManager" />
+ <constructor-arg ref="extensionManifestParser" />
+ </bean>
+
<!-- bulletin repository -->
<bean id="bulletinRepository" class="org.apache.nifi.events.VolatileBulletinRepository" />
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/manifest/StandardRuntimeManifestServiceTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/manifest/StandardRuntimeManifestServiceTest.java
new file mode 100644
index 0000000..d644f64
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/manifest/StandardRuntimeManifestServiceTest.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.manifest;
+
+import org.apache.nifi.bundle.Bundle;
+import org.apache.nifi.bundle.BundleCoordinate;
+import org.apache.nifi.bundle.BundleDetails;
+import org.apache.nifi.c2.protocol.component.api.ComponentManifest;
+import org.apache.nifi.c2.protocol.component.api.ControllerServiceDefinition;
+import org.apache.nifi.c2.protocol.component.api.ProcessorDefinition;
+import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
+import org.apache.nifi.extension.manifest.parser.ExtensionManifestParser;
+import org.apache.nifi.extension.manifest.parser.jaxb.JAXBExtensionManifestParser;
+import org.apache.nifi.nar.ExtensionManager;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class StandardRuntimeManifestServiceTest {
+
+ private Bundle frameworkBundle;
+ private Bundle testComponentsBundle;
+ private ExtensionManager extensionManager;
+ private ExtensionManifestParser extensionManifestParser;
+ private RuntimeManifestService runtimeManifestService;
+
+ @BeforeEach
+ public void setup() {
+ final BundleDetails frameworkBundleDetails = new BundleDetails.Builder()
+ .coordinate(new BundleCoordinate("org.apache.nifi", "nifi-framework-nar", "1.16.0"))
+ .buildJdk("1.8.0")
+ .buildRevision("revision1")
+ .buildTimestamp("2022-03-07T08:54:46Z")
+ .workingDir(new File("src/test/resources/TestRuntimeManifest/nifi-framework-nar"))
+ .build();
+
+ frameworkBundle = new Bundle(frameworkBundleDetails, this.getClass().getClassLoader());
+
+ final BundleDetails testComponentsBundleDetails = new BundleDetails.Builder()
+ .coordinate(new BundleCoordinate("org.apache.nifi", "nifi-test-components-nar", "1.16.0"))
+ .buildJdk("1.8.0")
+ .buildRevision("revision1")
+ .buildTimestamp("2022-03-07T08:54:46Z")
+ .workingDir(new File("src/test/resources/TestRuntimeManifest/nifi-test-components-nar"))
+ .build();
+
+ testComponentsBundle = new Bundle(testComponentsBundleDetails, this.getClass().getClassLoader());
+
+ extensionManager = mock(ExtensionManager.class);
+ extensionManifestParser = new JAXBExtensionManifestParser();
+ runtimeManifestService = new TestableRuntimeManifestService(extensionManager, extensionManifestParser, frameworkBundle);
+ }
+
+ @Test
+ public void testGetRuntimeManifest() {
+ when(extensionManager.getAllBundles()).thenReturn(new HashSet<>(Arrays.asList(testComponentsBundle)));
+
+ final RuntimeManifest runtimeManifest = runtimeManifestService.getManifest();
+ assertNotNull(runtimeManifest);
+ assertEquals(frameworkBundle.getBundleDetails().getCoordinate().getVersion(), runtimeManifest.getVersion());
+
+ assertEquals(frameworkBundle.getBundleDetails().getCoordinate().getVersion(), runtimeManifest.getBuildInfo().getVersion());
+ assertEquals(frameworkBundle.getBundleDetails().getBuildRevision(), runtimeManifest.getBuildInfo().getRevision());
+ assertEquals(frameworkBundle.getBundleDetails().getBuildJdk(), runtimeManifest.getBuildInfo().getCompiler());
+
+ final List<org.apache.nifi.c2.protocol.component.api.Bundle> bundles = runtimeManifest.getBundles();
+ assertNotNull(bundles);
+ assertEquals(1, bundles.size());
+
+ final org.apache.nifi.c2.protocol.component.api.Bundle testComponentsManifestBundle = bundles.get(0);
+ assertEquals(testComponentsBundle.getBundleDetails().getCoordinate().getGroup(), testComponentsManifestBundle.getGroup());
+ assertEquals(testComponentsBundle.getBundleDetails().getCoordinate().getId(), testComponentsManifestBundle.getArtifact());
+ assertEquals(testComponentsBundle.getBundleDetails().getCoordinate().getVersion(), testComponentsManifestBundle.getVersion());
+
+ final ComponentManifest testComponentsManifest = testComponentsManifestBundle.getComponentManifest();
+ assertNotNull(testComponentsManifest);
+
+ final List<ProcessorDefinition> processorDefinitions = testComponentsManifest.getProcessors();
+ assertEquals(3, processorDefinitions.size());
+
+ final List<ControllerServiceDefinition> controllerServiceDefinitions = testComponentsManifest.getControllerServices();
+ assertEquals(1, controllerServiceDefinitions.size());
+ }
+
+ /**
+ * Override getFrameworkBundle to provide a mocked Bundle.
+ */
+ private static class TestableRuntimeManifestService extends StandardRuntimeManifestService {
+
+ private Bundle frameworkBundle;
+
+ public TestableRuntimeManifestService(final ExtensionManager extensionManager, final ExtensionManifestParser extensionManifestParser, final Bundle frameworkBundle) {
+ super(extensionManager, extensionManifestParser);
+ this.frameworkBundle = frameworkBundle;
+ }
+
+ @Override
+ Bundle getFrameworkBundle() {
+ return frameworkBundle;
+ }
+ }
+}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/resources/TestRuntimeManifest/nifi-framework-nar/META-INF/docs/extension-manifest.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/resources/TestRuntimeManifest/nifi-framework-nar/META-INF/docs/extension-manifest.xml
new file mode 100644
index 0000000..a67c2d2
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/resources/TestRuntimeManifest/nifi-framework-nar/META-INF/docs/extension-manifest.xml
@@ -0,0 +1,19 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<extensionManifest>
+ <systemApiVersion>1.8.0</systemApiVersion>
+ <extensions>
+ </extensions>
+</extensionManifest>
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/resources/TestRuntimeManifest/nifi-test-components-nar/META-INF/docs/extension-manifest.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/resources/TestRuntimeManifest/nifi-test-components-nar/META-INF/docs/extension-manifest.xml
new file mode 100644
index 0000000..d2d99a0
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/resources/TestRuntimeManifest/nifi-test-components-nar/META-INF/docs/extension-manifest.xml
@@ -0,0 +1,87 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<extensionManifest>
+ <systemApiVersion>1.8.0</systemApiVersion>
+ <extensions>
+ <extension>
+ <name>org.apache.nifi.processors.TestProcessor1</name>
+ <type>PROCESSOR</type>
+ <description>Test processor 1.</description>
+ <tags>
+ <tag>test</tag>
+ <tag>processor</tag>
+ </tags>
+ <triggerSerially>true</triggerSerially>
+ <triggerWhenEmpty>true</triggerWhenEmpty>
+ <triggerWhenAnyDestinationAvailable>true</triggerWhenAnyDestinationAvailable>
+ <primaryNodeOnly>true</primaryNodeOnly>
+ <supportsBatching>true</supportsBatching>
+ <eventDriven>true</eventDriven>
+ <sideEffectFree>true</sideEffectFree>
+ <defaultSettings>
+ <yieldDuration>10 secs</yieldDuration>
+ <penaltyDuration>20 secs</penaltyDuration>
+ <bulletinLevel>DEBUG</bulletinLevel>
+ </defaultSettings>
+ <defaultSchedule>
+ <strategy>CRON_DRIVEN</strategy>
+ <period>* 1 * * *</period>
+ <concurrentTasks>5</concurrentTasks>
+ </defaultSchedule>
+ </extension>
+ <extension>
+ <name>org.apache.nifi.processors.TestProcessor2</name>
+ <type>PROCESSOR</type>
+ <description>Test processor 2.</description>
+ <tags>
+ <tag>test</tag>
+ <tag>processor</tag>
+ </tags>
+ <restricted>
+ <restrictions>
+ <restriction>
+ <requiredPermission>write filesystem</requiredPermission>
+ <explanation>Test explanation.</explanation>
+ </restriction>
+ </restrictions>
+ </restricted>
+ </extension>
+ <extension>
+ <name>org.apache.nifi.processors.TestProcessor3</name>
+ <type>PROCESSOR</type>
+ <description/>
+ <tags>
+ </tags>
+ </extension>
+ <extension>
+ <name>org.apache.nifi.service.TestServiceImpl</name>
+ <type>CONTROLLER_SERVICE</type>
+ <deprecationNotice/>
+ <description>Test service.</description>
+ <tags>
+ <tag>test</tag>
+ <tag>service</tag>
+ </tags>
+ <providedServiceAPIs>
+ <providedServiceAPI>
+ <className>org.apache.nifi.service.TestService</className>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-test-service-api-nar</artifactId>
+ <version>1.0.0</version>
+ </providedServiceAPI>
+ </providedServiceAPIs>
+ </extension>
+ </extensions>
+</extensionManifest>
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 4a34aa6..a762d8a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -31,8 +31,6 @@ import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.bundle.Bundle;
import org.apache.nifi.bundle.BundleCoordinate;
-import org.apache.nifi.bundle.BundleDetails;
-import org.apache.nifi.c2.protocol.component.api.BuildInfo;
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.components.ConfigurableComponent;
@@ -64,17 +62,15 @@ import org.apache.nifi.controller.status.analytics.StatusAnalytics;
import org.apache.nifi.controller.status.analytics.StatusAnalyticsEngine;
import org.apache.nifi.controller.status.history.StatusHistoryRepository;
import org.apache.nifi.diagnostics.SystemDiagnostics;
-import org.apache.nifi.extension.manifest.ExtensionManifest;
-import org.apache.nifi.extension.manifest.parser.ExtensionManifestParser;
import org.apache.nifi.flow.VersionedProcessGroup;
import org.apache.nifi.flowfile.FlowFilePrioritizer;
import org.apache.nifi.flowfile.attributes.CoreAttributes;
import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.groups.ProcessGroupCounts;
import org.apache.nifi.groups.RemoteProcessGroup;
+import org.apache.nifi.manifest.RuntimeManifestService;
import org.apache.nifi.nar.ExtensionDefinition;
import org.apache.nifi.nar.ExtensionManager;
-import org.apache.nifi.nar.NarClassLoadersHolder;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.provenance.ProvenanceEventRecord;
@@ -91,9 +87,6 @@ import org.apache.nifi.remote.PublicPort;
import org.apache.nifi.remote.RemoteGroupPort;
import org.apache.nifi.reporting.BulletinRepository;
import org.apache.nifi.reporting.ReportingTask;
-import org.apache.nifi.runtime.manifest.RuntimeManifestBuilder;
-import org.apache.nifi.runtime.manifest.impl.SchedulingDefaultsFactory;
-import org.apache.nifi.runtime.manifest.impl.StandardRuntimeManifestBuilder;
import org.apache.nifi.services.FlowService;
import org.apache.nifi.util.BundleUtils;
import org.apache.nifi.util.FormatUtils;
@@ -126,8 +119,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.WebApplicationException;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.Collator;
@@ -141,7 +132,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import java.util.SortedSet;
import java.util.TimeZone;
@@ -155,9 +145,6 @@ public class ControllerFacade implements Authorizable {
private static final Logger logger = LoggerFactory.getLogger(ControllerFacade.class);
- private static final String RUNTIME_MANIFEST_IDENTIFIER = "nifi";
- private static final String RUNTIME_TYPE = "nifi";
-
// nifi components
private FlowController flowController;
private FlowService flowService;
@@ -168,7 +155,7 @@ public class ControllerFacade implements Authorizable {
private DtoFactory dtoFactory;
private SearchQueryParser searchQueryParser;
private ControllerSearchService controllerSearchService;
- private ExtensionManifestParser extensionManifestParser;
+ private RuntimeManifestService runtimeManifestService;
private ProcessGroup getRootGroup() {
return flowController.getFlowManager().getRootGroup();
@@ -587,53 +574,7 @@ public class ControllerFacade implements Authorizable {
* @return the runtime manifest
*/
public RuntimeManifest getRuntimeManifest() {
- final ExtensionManager extensionManager = getExtensionManager();
- final Set<Bundle> allBundles = extensionManager.getAllBundles();
-
- final Bundle frameworkBundle = NarClassLoadersHolder.getInstance().getFrameworkBundle();
- final BundleDetails frameworkDetails = frameworkBundle.getBundleDetails();
- final Date frameworkBuildDate = frameworkDetails.getBuildTimestampDate();
-
- final BuildInfo buildInfo = new BuildInfo();
- buildInfo.setVersion(frameworkDetails.getCoordinate().getVersion());
- buildInfo.setRevision(frameworkDetails.getBuildRevision());
- buildInfo.setCompiler(frameworkDetails.getBuildJdk());
- buildInfo.setTimestamp(frameworkBuildDate == null ? null : frameworkBuildDate.getTime());
-
- final RuntimeManifestBuilder manifestBuilder = new StandardRuntimeManifestBuilder()
- .identifier(RUNTIME_MANIFEST_IDENTIFIER)
- .runtimeType(RUNTIME_TYPE)
- .version(buildInfo.getVersion())
- .schedulingDefaults(SchedulingDefaultsFactory.getNifiSchedulingDefaults())
- .buildInfo(buildInfo);
-
- for (final Bundle bundle : allBundles) {
- getExtensionManifest(bundle).ifPresent(em -> manifestBuilder.addBundle(em));
- }
-
- return manifestBuilder.build();
- }
-
- private Optional<ExtensionManifest> getExtensionManifest(final Bundle bundle) {
- final BundleDetails bundleDetails = bundle.getBundleDetails();
- final File manifestFile = new File(bundleDetails.getWorkingDirectory(), "META-INF/docs/extension-manifest.xml");
- if (!manifestFile.exists()) {
- logger.warn("Unable to find extension manifest for [{}] at [{}]...", bundleDetails.getCoordinate(), manifestFile.getAbsolutePath());
- return Optional.empty();
- }
-
- try (final InputStream inputStream = new FileInputStream(manifestFile)) {
- final ExtensionManifest extensionManifest = extensionManifestParser.parse(inputStream);
- // Newer NARs will have these fields populated in extension-manifest.xml, but older NARs will not, so we can
- // set the values from the BundleCoordinate which already has the group, artifact id, and version
- extensionManifest.setGroupId(bundleDetails.getCoordinate().getGroup());
- extensionManifest.setArtifactId(bundleDetails.getCoordinate().getId());
- extensionManifest.setVersion(bundleDetails.getCoordinate().getVersion());
- return Optional.of(extensionManifest);
- } catch (final IOException e) {
- logger.error("Unable to load extension manifest for bundle [{}]", bundleDetails.getCoordinate(), e);
- return Optional.empty();
- }
+ return runtimeManifestService.getManifest();
}
/**
@@ -1760,7 +1701,7 @@ public class ControllerFacade implements Authorizable {
this.controllerSearchService = controllerSearchService;
}
- public void setExtensionManifestParser(ExtensionManifestParser extensionManifestParser) {
- this.extensionManifestParser = extensionManifestParser;
+ public void setRuntimeManifestService(RuntimeManifestService runtimeManifestService) {
+ this.runtimeManifestService = runtimeManifestService;
}
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
index 6ba3479..7b06418 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
@@ -290,7 +290,6 @@
<property name="matcherForLabel" ref="matcherForLabel" />
<property name="matcherForControllerServiceNode" ref="matcherForControllerServiceNode" />
</bean>
- <bean id="extensionManifestParser" class="org.apache.nifi.extension.manifest.parser.jaxb.JAXBExtensionManifestParser" />
<bean id="controllerFacade" class="org.apache.nifi.web.controller.ControllerFacade">
<property name="flowController" ref="flowController"/>
<property name="flowService" ref="flowService"/>
@@ -299,7 +298,7 @@
<property name="dtoFactory" ref="dtoFactory"/>
<property name="searchQueryParser" ref="searchQueryParser"/>
<property name="controllerSearchService" ref="controllerSearchService"/>
- <property name="extensionManifestParser" ref="extensionManifestParser" />
+ <property name="runtimeManifestService" ref="runtimeManifestService" />
</bean>
<bean id="authorizableLookup" class="org.apache.nifi.authorization.StandardAuthorizableLookup">
<property name="controllerFacade" ref="controllerFacade"/>