From 500086b9cc6f6b528faaf4348bddf85dc86b8dca Mon Sep 17 00:00:00 2001 From: David Radley Date: Fri, 10 Mar 2023 13:09:10 +0000 Subject: [PATCH 1/5] git7512 Signed-off-by: David Radley --- .../server-standalone/pom.xml | 36 + .../server-standalone-spring/build.gradle | 139 +++ .../server-standalone-spring/pom.xml | 881 ++++++++++++++++++ .../springboot/OMAGServerPlatform.java | 236 +++++ .../springboot/StartupFailEvent.java | 30 + .../src/main/resources/application.properties | 58 ++ .../src/main/resources/banner.txt | 9 + .../src/main/resources/keystore.p12 | Bin 0 -> 6250 bytes .../src/main/resources/truststore.p12 | Bin 0 -> 1927 bytes pom.xml | 7 + settings.gradle | 2 + 11 files changed, 1398 insertions(+) create mode 100644 open-metadata-implementation/server-standalone/pom.xml create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StartupFailEvent.java create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/banner.txt create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/keystore.p12 create mode 100644 open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/truststore.p12 diff --git a/open-metadata-implementation/server-standalone/pom.xml b/open-metadata-implementation/server-standalone/pom.xml new file mode 100644 index 00000000000..d2ff5364975 --- /dev/null +++ b/open-metadata-implementation/server-standalone/pom.xml @@ -0,0 +1,36 @@ + + + + + + + + + + open-metadata-implementation + org.odpi.egeria + 4.0-SNAPSHOT + + + 4.0.0 + + + scm:git:git://github.com/odpi/egeria.git + scm:git:ssh://github.com/odpi/egeria.git + http://github.com/odpi/egeria/tree/main + + + Standalone Server + + A standalone server to host open metadata services. + + + server-standalone + pom + + server-standalone-spring + + + diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle new file mode 100644 index 00000000000..8e517a72fb7 --- /dev/null +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle @@ -0,0 +1,139 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Contributors to the ODPi Egeria project. + */ + +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin") + } +} + +plugins { + id 'org.springframework.boot' +} + +dependencies { + implementation 'org.springframework.boot:spring-boot' + testImplementation('org.springframework.boot:spring-boot-starter-test') + implementation 'org.springframework.boot:spring-boot-autoconfigure' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.apache.tomcat.embed:tomcat-embed-core' + //implementation 'org.springframework.boot:spring-boot-starter-tomcat' + //implementation 'javax.servlet:javax.servlet-api' + // Explicitly needed for gradle - added by maven plugin + + runtimeOnly 'io.micrometer:micrometer-registry-prometheus' + implementation 'org.springframework:spring-beans' + implementation 'org.springframework:spring-core' + implementation 'org.springframework:spring-context' + + compileOnly project(':open-metadata-implementation:common-services:ffdc-services') + + runtimeOnly 'ch.qos.logback:logback-classic' + implementation project(':open-metadata-implementation:adapters:authentication-plugins:http-helper') + implementation 'org.slf4j:slf4j-api' + runtimeOnly 'org.springdoc:springdoc-openapi-ui' + implementation 'io.swagger.core.v3:swagger-annotations' + runtimeOnly 'org.hibernate:hibernate-validator' + runtimeOnly project(':open-metadata-implementation:platform-services:platform-services-spring') + + // The following are only included at runtime for the full platform (ie adminChassisOnly is not set as a property) + if (!project.hasProperty("adminChassisOnly")) { + runtimeOnly project(':open-metadata-implementation:view-services:server-author-view:server-author-view-spring') + runtimeOnly project(':open-metadata-implementation:view-services:glossary-author-view:glossary-author-view-spring') + runtimeOnly project(':open-metadata-implementation:view-services:rex-view:rex-view-spring') + runtimeOnly project(':open-metadata-implementation:view-services:tex-view:tex-view-spring') + runtimeOnly project(':open-metadata-implementation:view-services:dino-view:dino-view-spring') + runtimeOnly project(':open-metadata-implementation:access-services:security-officer:security-officer-spring') + runtimeOnly project(':open-metadata-implementation:access-services:security-manager:security-manager-spring') + runtimeOnly project(':open-metadata-implementation:access-services:data-manager:data-manager-spring') + runtimeOnly project(':open-metadata-implementation:governance-servers:open-lineage-services:open-lineage-services-spring') + runtimeOnly project(':open-metadata-implementation:access-services:glossary-view:glossary-view-spring') + runtimeOnly project(':open-metadata-implementation:access-services:asset-lineage:asset-lineage-spring') + runtimeOnly project(':open-metadata-implementation:governance-servers:data-engine-proxy-services:data-engine-proxy-services-spring') + runtimeOnly project(':open-metadata-implementation:access-services:data-engine:data-engine-spring') + runtimeOnly project(':open-metadata-implementation:access-services:subject-area:subject-area-spring') + runtimeOnly project(':open-metadata-implementation:access-services:analytics-modeling:analytics-modeling-spring') + runtimeOnly project(':open-metadata-implementation:access-services:asset-catalog:asset-catalog-spring') + runtimeOnly project(':open-metadata-implementation:access-services:governance-program:governance-program-spring') + runtimeOnly project(':open-metadata-implementation:access-services:governance-engine:governance-engine-spring') + runtimeOnly project(':open-metadata-implementation:engine-services:governance-action:governance-action-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:security-integrator:security-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:organization-integrator:organization-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:infrastructure-integrator:infrastructure-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:lineage-integrator:lineage-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:files-integrator:files-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:display-integrator:display-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:database-integrator:database-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:analytics-integrator:analytics-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:api-integrator:api-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:catalog-integrator:catalog-integrator-spring') + runtimeOnly project(':open-metadata-implementation:access-services:discovery-engine:discovery-engine-spring') + runtimeOnly project(':open-metadata-implementation:access-services:stewardship-action:stewardship-action-spring') + runtimeOnly project(':open-metadata-implementation:access-services:community-profile:community-profile-spring') + runtimeOnly project(':open-metadata-implementation:access-services:design-model:design-model-spring') + runtimeOnly project(':open-metadata-implementation:access-services:data-privacy:data-privacy-spring') + runtimeOnly project(':open-metadata-implementation:access-services:it-infrastructure:it-infrastructure-spring') + runtimeOnly project(':open-metadata-implementation:access-services:project-management:project-management-spring') + runtimeOnly project(':open-metadata-implementation:access-services:dev-ops:dev-ops-spring') + runtimeOnly project(':open-metadata-implementation:access-services:software-developer:software-developer-spring') + runtimeOnly project(':open-metadata-implementation:access-services:digital-architecture:digital-architecture-spring') + runtimeOnly project(':open-metadata-implementation:access-services:digital-service:digital-service-spring') + runtimeOnly project(':open-metadata-implementation:access-services:data-science:data-science-spring') + runtimeOnly project(':open-metadata-implementation:engine-services:repository-governance:repository-governance-spring') + runtimeOnly project(':open-metadata-implementation:access-services:asset-consumer:asset-consumer-spring') + runtimeOnly project(':open-metadata-implementation:access-services:asset-manager:asset-manager-spring') + runtimeOnly project(':open-metadata-implementation:access-services:asset-owner:asset-owner-spring') + runtimeOnly project(':open-metadata-implementation:engine-services:asset-analysis:asset-analysis-spring') + runtimeOnly project(':open-metadata-implementation:repository-services:repository-services-spring') + runtimeOnly project(':open-metadata-conformance-suite:open-metadata-conformance-suite-spring') + runtimeOnly project(':open-metadata-implementation:framework-services:ocf-metadata-management:ocf-metadata-spring') + // originally not in gradle build at all + runtimeOnly project(':open-metadata-implementation:framework-services:gaf-metadata-management:gaf-metadata-spring') + // Not in original maven adminChassisOnly profile, but proposed + runtimeOnly project(':open-metadata-implementation:governance-servers:integration-daemon-services:integration-daemon-services-spring') + runtimeOnly project(':open-metadata-implementation:governance-servers:engine-host-services:engine-host-services-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:search-integrator:search-integrator-spring') + runtimeOnly project(':open-metadata-implementation:integration-services:topic-integrator:topic-integrator-spring') + } +} + +description = 'OMAG Server Platform with standalone server for Spring' + +bootJar { + manifest { + attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher' + } +} + +java { + withJavadocJar() +} + +test { + useJUnitPlatform() +} + +// See https://stackoverflow.com/questions/61197984/bootjar-mavenjar-artifact-wasnt-produced-by-this-build +// Remove the regular (plain) jar & replace with the SpringBoot version +configurations { + [apiElements, runtimeElements].each { + it.outgoing.artifacts.removeIf { + it.buildDependencies.getDependencies(null).contains(jar) + } + it.outgoing.artifact(bootJar) + } +} + +// Assuming the plugin has been applied +loggingCapabilities { + // Configuration goes here + enforceLogback() +} diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml b/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml new file mode 100644 index 00000000000..090130c1e15 --- /dev/null +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml @@ -0,0 +1,881 @@ + + + + + + + + + server-standalone + org.odpi.egeria + 4.0-SNAPSHOT + + + 4.0.0 + + + scm:git:git://github.com/odpi/egeria.git + scm:git:ssh://github.com/odpi/egeria.git + http://github.com/odpi/egeria/tree/main + + + OMAG Server Platform and stand alone server for Spring + + Provides the spring-based OMAG standalone server. + + + server-standalone-spring + + + + + org.springframework.boot + spring-boot + + + + org.springframework.boot + spring-boot-autoconfigure + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.apache.logging.log4j + log4j-api + + + + + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework + spring-beans + + + + org.springframework + spring-context + + + + org.odpi.egeria + platform-services-spring + runtime + + + + org.odpi.egeria + search-integrator-api + runtime + + + + org.odpi.egeria + search-integrator-spring + runtime + + + + org.odpi.egeria + ocf-metadata-spring + runtime + + + + org.odpi.egeria + gaf-metadata-spring + runtime + + + + org.odpi.egeria + repository-services-spring + runtime + + + + org.odpi.egeria + open-metadata-conformance-suite-spring + runtime + + + + org.odpi.egeria + asset-analysis-spring + runtime + + + + org.odpi.egeria + asset-consumer-spring + runtime + + + + org.odpi.egeria + asset-manager-spring + runtime + + + + org.odpi.egeria + asset-owner-spring + runtime + + + + + org.odpi.egeria + asset-catalog-topic-connector + runtime + + + + org.odpi.egeria + discovery-engine-spring + runtime + + + + org.odpi.egeria + repository-governance-spring + runtime + + + + org.odpi.egeria + stewardship-action-spring + runtime + + + + org.odpi.egeria + community-profile-spring + runtime + + + + org.odpi.egeria + design-model-spring + runtime + + + + org.odpi.egeria + data-privacy-spring + runtime + + + + org.odpi.egeria + it-infrastructure-spring + runtime + + + + org.odpi.egeria + project-management-spring + runtime + + + + org.odpi.egeria + dev-ops-spring + runtime + + + + org.odpi.egeria + software-developer-spring + runtime + + + + org.odpi.egeria + digital-architecture-spring + runtime + + + + org.odpi.egeria + digital-service-spring + runtime + + + + org.odpi.egeria + api-integrator-spring + runtime + + + + org.odpi.egeria + analytics-integrator-spring + runtime + + + + org.odpi.egeria + catalog-integrator-spring + runtime + + + + org.odpi.egeria + database-integrator-spring + runtime + + + + org.odpi.egeria + display-integrator-spring + runtime + + + + org.odpi.egeria + files-integrator-spring + runtime + + + + org.odpi.egeria + lineage-integrator-spring + runtime + + + + org.odpi.egeria + infrastructure-integrator-spring + runtime + + + + org.odpi.egeria + organization-integrator-spring + runtime + + + + org.odpi.egeria + security-integrator-spring + runtime + + + + org.odpi.egeria + topic-integrator-spring + runtime + + + + org.odpi.egeria + data-science-spring + runtime + + + + org.odpi.egeria + governance-action-spring + runtime + + + + org.odpi.egeria + governance-engine-spring + runtime + + + + org.odpi.egeria + governance-program-spring + runtime + + + + org.odpi.egeria + asset-catalog-spring + runtime + + + + org.odpi.egeria + analytics-modeling-spring + runtime + + + + org.odpi.egeria + subject-area-spring + runtime + + + + org.odpi.egeria + data-engine-spring + runtime + + + + org.odpi.egeria + glossary-view-spring + runtime + + + + org.odpi.egeria + asset-lineage-spring + runtime + + + + org.odpi.egeria + open-lineage-services-spring + runtime + + + + org.odpi.egeria + integration-daemon-services-spring + runtime + + + + org.odpi.egeria + engine-host-services-spring + runtime + + + + org.odpi.egeria + data-manager-spring + runtime + + + + org.odpi.egeria + security-manager-spring + runtime + + + + org.odpi.egeria + security-officer-spring + runtime + + + + org.odpi.egeria + glossary-author-view-spring + runtime + + + + org.odpi.egeria + rex-view-spring + runtime + + + + org.odpi.egeria + tex-view-spring + runtime + + + + org.odpi.egeria + dino-view-spring + runtime + + + + org.odpi.egeria + server-author-view-spring + runtime + + + + org.odpi.egeria + data-engine-proxy-services-spring + runtime + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-validation + + + + ch.qos.logback + logback-classic + compile + + + + ch.qos.logback + logback-core + compile + + + + org.odpi.egeria + http-helper + + + + org.slf4j + slf4j-api + + + + org.springframework + spring-core + + + + + + org.springdoc + springdoc-openapi-ui + + + + io.swagger.core.v3 + swagger-annotations + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + ZIP + + + + + repackage + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + analyze + + analyze-only + + + + + org.odpi.egeria:*spring* + + org.odpi.egeria:*connector* + + + org.springframework.boot:spring-boot-starter-web:* + + org.springframework.boot:spring-boot-starter-validation:* + + + + org.springframework.boot:spring-boot-starter-security:* + + + org.springdoc:springdoc-openapi-ui:* + + + org.odpi.egeria:search-integrator-api:* + + + + + javax.annotation:javax.annotation-api:* + + + + + + + + + + + + + + full-platform + + + !adminChassisOnly + + + + + org.odpi.egeria + ocf-metadata-spring + runtime + + + + org.odpi.egeria + gaf-metadata-spring + runtime + + + + org.odpi.egeria + repository-services-spring + runtime + + + + org.odpi.egeria + open-metadata-conformance-suite-spring + runtime + + + + org.odpi.egeria + asset-analysis-spring + runtime + + + + org.odpi.egeria + asset-consumer-spring + runtime + + + + org.odpi.egeria + asset-manager-spring + runtime + + + + org.odpi.egeria + asset-owner-spring + runtime + + + + org.odpi.egeria + repository-governance-spring + runtime + + + + org.odpi.egeria + discovery-engine-spring + runtime + + + + org.odpi.egeria + stewardship-action-spring + runtime + + + + org.odpi.egeria + community-profile-spring + runtime + + + + org.odpi.egeria + design-model-spring + runtime + + + + org.odpi.egeria + data-privacy-spring + runtime + + + + org.odpi.egeria + it-infrastructure-spring + runtime + + + + org.odpi.egeria + project-management-spring + runtime + + + + org.odpi.egeria + dev-ops-spring + runtime + + + + org.odpi.egeria + software-developer-spring + runtime + + + + org.odpi.egeria + digital-architecture-spring + runtime + + + + org.odpi.egeria + digital-service-spring + runtime + + + + org.odpi.egeria + data-science-spring + runtime + + + + org.odpi.egeria + api-integrator-spring + runtime + + + + org.odpi.egeria + analytics-integrator-spring + runtime + + + + org.odpi.egeria + catalog-integrator-spring + runtime + + + + org.odpi.egeria + database-integrator-spring + runtime + + + + org.odpi.egeria + display-integrator-spring + runtime + + + + org.odpi.egeria + files-integrator-spring + runtime + + + + org.odpi.egeria + lineage-integrator-spring + runtime + + + + org.odpi.egeria + infrastructure-integrator-spring + runtime + + + + org.odpi.egeria + organization-integrator-spring + runtime + + + + org.odpi.egeria + security-integrator-spring + runtime + + + + org.odpi.egeria + governance-action-spring + runtime + + + + org.odpi.egeria + governance-engine-spring + runtime + + + + org.odpi.egeria + governance-program-spring + runtime + + + + org.odpi.egeria + asset-catalog-spring + runtime + + + + org.odpi.egeria + analytics-modeling-spring + runtime + + + + org.odpi.egeria + subject-area-spring + runtime + + + + org.odpi.egeria + data-engine-spring + runtime + + + + org.odpi.egeria + data-engine-proxy-services-spring + runtime + + + + org.odpi.egeria + glossary-view-spring + runtime + + + + org.odpi.egeria + asset-lineage-spring + runtime + + + + org.odpi.egeria + open-lineage-services-spring + runtime + + + + org.odpi.egeria + data-manager-spring + runtime + + + + org.odpi.egeria + security-officer-spring + runtime + + + + org.odpi.egeria + security-manager-spring + runtime + + + + org.odpi.egeria + glossary-author-view-spring + runtime + + + + org.odpi.egeria + rex-view-spring + runtime + + + + org.odpi.egeria + tex-view-spring + runtime + + + + org.odpi.egeria + dino-view-spring + runtime + + + + org.odpi.egeria + server-author-view-spring + runtime + + + + + openapi + + + openapi + + + + + + org.springdoc + springdoc-openapi-maven-plugin + + + integration-test + + generate + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + pre-integration-test + + start + + + + post-integration-test + + stop + + + + + + + + + diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java new file mode 100644 index 00000000000..691c34594ee --- /dev/null +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright Contributors to the ODPi Egeria project. */ +package main.java.org.odpi.openmetadata.serverstandalone.springboot; + +import io.swagger.v3.oas.annotations.ExternalDocumentation; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Contact; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.info.License; +import org.odpi.openmetadata.adminservices.server.OMAGServerOperationalServices; +import org.odpi.openmetadata.adminservices.rest.SuccessMessageResponse; +import org.odpi.openmetadata.http.HttpHelper; +import org.odpi.openmetadata.http.HttpRequestHeadersFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; +import java.util.*; + + +@SpringBootApplication( + scanBasePackages = {"${scan.packages}"} +) +@OpenAPIDefinition( + info = @Info( + title = "Egeria's Open Metadata and Governance (OMAG) Server Platform", + version = "4.0-SNAPSHOT", + description = "The OMAG Server Platform provides a runtime process and platform for Open Metadata and Governance (OMAG) Services.\n" + + "\n" + + "The OMAG services are configured and activated in OMAG Servers using the Administration Services.\n" + + "The configuration operations of the admin services create configuration documents, one for each OMAG Server. " + + "Inside a configuration document is the definition of which OMAG services to activate in the server. " + + "These include the repository services (any type of server), the access services (for metadata access points " + + "and metadata servers), governance services (for governance servers) and view services (for view servers). " + + "Once a configuration document is defined, the OMAG Server can be started and stopped multiple times by " + + "the admin services server instance operations. \n" + + "\n" + + "The OMAG Server Platform also supports platform services to query details of the servers running on the platform.\n" + + "\n" + + "The OMAG Server Platform can host multiple OMAG servers at any one time. " + + "Each OMAG server is isolated within the server platform and so the OMAG server platform can be used to support multi-tenant " + + "operation for a cloud service, " + + "or host a variety of different OMAG Servers needed at a particular location.\n" + + "\n" + + "NOTE: many REST APIs are not guaranteed to be backward-compatible from release to release since they have supported Java clients. " + + "REST APIs may be used for development, testing, evaluation. Click on the documentation for each module to discover more ...", + license = @License(name = "Apache 2.0 License", url = "https://www.apache.org/licenses/LICENSE-2.0"), + contact = @Contact(url = "https://egeria-project.org", name = "Egeria Project", + email = "egeria-technical-discuss@lists.lfaidata.foundation") + ), + + externalDocs = @ExternalDocumentation(description = "OMAG Server Platform documentation", + url="https://egeria-project.org/concepts/omag-server-platform/") + ) + + +@Configuration +public class OMAGServerPlatform +{ + @Value("${strict.ssl}") + Boolean strictSSL; + + @Value("${startup.user}") + String sysUser; + + @Value("${startup.server.list}") + String startupServers; + + @Value("${header.name.list}") + List headerNames; + + @Autowired + private Environment env; + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + private boolean triggeredRuntimeHalt = false; + private String startupMessage = ""; + private OMAGServerOperationalServices operationalServices = new OMAGServerOperationalServices(); + + private static final Logger log = LoggerFactory.getLogger(OMAGServerPlatform.class); + + public static void main(String[] args) { + SpringApplication.run(OMAGServerPlatform.class, args); + } + + @Bean + public InitializingBean getInitialize() + { + return () -> { + if (!strictSSL) + { + log.warn("strict.ssl is set to false! Invalid certificates will be accepted for connection!"); + HttpHelper.noStrictSSL(); + } else if( System.getProperty("javax.net.ssl.trustStore")==null ) { + //load the 'javax.net.ssl.trustStore' and + //'javax.net.ssl.trustStorePassword' from application.properties + System.setProperty("javax.net.ssl.trustStore", env.getProperty("server.ssl.trust-store")); + System.setProperty("javax.net.ssl.trustStorePassword", env.getProperty("server.ssl.trust-store-password")); + } + }; + } + + /** + * Extract the list of servers to auto start along with the administration userId. + * The userId is in property "sysUser" and the list of server names are in property + * "startupServers". If either are null then no servers are auto started. + */ + List getAutoStartList() + { + if (!startupServers.trim().isEmpty()) + { + String[] splits = startupServers.split(","); + //remove eventual duplicates + TreeSet serverSet = new TreeSet(); + + Collections.addAll(serverSet, splits); + + if (! serverSet.isEmpty()) + { + return new ArrayList<>(serverSet); + } + } + + return null; + } + + /** + * Starts the servers specified in the startup.server.list property + */ + private void autoStartConfig() + { + List servers = getAutoStartList(); + + if (servers != null) + { + log.info("Startup detected for servers: {}", startupServers); + } + + SuccessMessageResponse response = operationalServices.activateServerListWithStoredConfig(sysUser.trim(), servers); + + if (response.getRelatedHTTPCode() == 200) + { + startupMessage = response.getSuccessMessage(); + } + else + { + startupMessage = "Server startup failed with error: " + response.getExceptionErrorMessage(); + + StartupFailEvent customSpringEvent = new StartupFailEvent(this, startupMessage); + applicationEventPublisher.publishEvent(customSpringEvent); + triggeredRuntimeHalt = true; + } + } + + + /** + * Deactivate all servers that were started automatically + */ + private void temporaryDeactivateServers() + { + List servers = getAutoStartList(); + + if (servers != null) + { + log.info("Temporarily deactivating any auto-started servers '{}'", servers); + + System.out.println(new Date() + " OMAG Server Platform shutdown requested. Shutting down auto-started servers (if running): " + servers); + + operationalServices.deactivateTemporarilyServerList(sysUser, servers); + } + } + + @Component + public class ApplicationContextListener + { + + @EventListener(ApplicationReadyEvent.class) + public void applicationReady() { + autoStartConfig(); + System.out.println(OMAGServerPlatform.this.startupMessage); + + if(triggeredRuntimeHalt){ + Runtime.getRuntime().halt(43); + } + System.out.println(new Date() + " OMAG server platform ready for more configuration"); + } + + @EventListener + public void onApplicationEvent(ContextClosedEvent event) + { + temporaryDeactivateServers(); + } + } + + @Component + public class CustomSpringEventListener implements ApplicationListener + { + @Override + public void onApplicationEvent(StartupFailEvent event) { + log.info("Received startup fail event with message: {} " + event.getMessage()); + temporaryDeactivateServers(); + } + + } + + /** + * Initialization of HttpRequestHeadersFilter. headerNames is a list of headers defined in application properties. + * @return bean of an initialized FilterRegistrationBean + */ + @Bean + public FilterRegistrationBean getRequestHeadersFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + + registrationBean.setFilter(new HttpRequestHeadersFilter(headerNames)); + registrationBean.addUrlPatterns("/*"); + registrationBean.setOrder(1); + + return registrationBean; + } + +} diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StartupFailEvent.java b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StartupFailEvent.java new file mode 100644 index 00000000000..76500e061fb --- /dev/null +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StartupFailEvent.java @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright Contributors to the ODPi Egeria project. */ +package org.odpi.openmetadata.serverstandalone.springboot; + +import org.springframework.context.ApplicationEvent; + +/** + * Application event used for the case of startup list fails + */ +public class StartupFailEvent extends ApplicationEvent { + + private static final long serialVersionUID = 1L; + + private Object source; + private String message; + + public StartupFailEvent(Object source, String message) { + super(source); + this.source = source; + this.message = message; + } + + public Object getSource() { + return source; + } + + public String getMessage() { + return message; + } +} diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties new file mode 100644 index 00000000000..b2720e96b38 --- /dev/null +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the ODPi Egeria project. + + +server.port=9443 +server.ssl.key-store=classpath:keystore.p12 +server.ssl.key-store-password=egeria +server.ssl.keyStoreType=PKCS12 +server.ssl.keyAlias=egeriaserverchassis + +server.ssl.trust-store=truststore.p12 +server.ssl.trust-store-password=egeria + +# WARNING! setting 'false' allows java clients to open https connections without checking certificates validity +# Alternate you can import self signed certificates into java truststore or setup an truststore only for this app +# by adding the store into server.ssl.trust-store parameter +strict.ssl=true + +################################################ +### startup servers configuration +################################################ +scan.packages=org.odpi.openmetadata.* +#userId used to startup the list of configured servers default is 'system' +startup.user=system +# Comma separated names of servers to be started +startup.server.list= +# Comma separated values of http headers to be added to ThreadLocal +header.name.list= + +################################################ +### Logging +################################################ +logging.level.root=OFF +logging.level.org.springframework=ERROR +#logging.level.org.odpi.openmetadata.commonservices=DEBUG +#logging.level.org.odpi.openmetadata.accessservices.subjectarea.handlers=DEBUG +logging.level.org.springframework.boot.web.embedded.tomcat=INFO +logging.level.org.odpi.openmetadata.serverchassis.springboot=INFO + +################################################ +### Swagger Docs +################################################ +springdoc.version='@springdoc.version@' +springdoc.api-docs.enabled=true +springdoc.api-docs.path=/v3/api-docs +springdoc.swagger-ui.path=/swagger-ui.html +springdoc.swagger-ui.displayRequestDuration=true +springdoc.swagger-ui.tagsSorter=alpha +springdoc.swagger-ui.operationsSorter=alpha +springdoc.swagger-ui.docExpansion=none + +################################################ +### Spring Boot Actuator +################################################ +# Endpoints web configuration +#management.endpoints.web.exposure.include=* +management.health.cassandra.enabled=false + diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/banner.txt b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/banner.txt new file mode 100644 index 00000000000..cf172f804cd --- /dev/null +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/banner.txt @@ -0,0 +1,9 @@ +${AnsiColor.CYAN} Project Egeria - Open Metadata and Governance +${AnsiColor.CYAN} ____ __ ___ ___ ______ _____ ____ _ _ ___ +${AnsiColor.CYAN} / __ \ / |/ // | / ____/ / ___/ ___ ____ _ __ ___ ____ / _ \ / / __ / / / _ /__ ____ _ _ +${AnsiColor.CYAN} / / / // /|_/ // /| | / / __ \__ \ / _ \ / __/| | / // _ \ / __/ / /_/ // // | / _\ / /_ / | / _// || | +${AnsiColor.CYAN} / /_/ // / / // ___ |/ /_/ / ___/ // __// / | |/ // __// / / __ // // / \ / /_ / _// / // / / / / / +${AnsiColor.CYAN} \____//_/ /_//_/ |_|\____/ /____/ \___//_/ |___/ \___//_/ /_/ /_/ \__/\//___//_/ \__//_/ /_/ /_/ +${AnsiColor.CYAN} +${AnsiColor.CYAN} :: Powered by Spring Boot${spring-boot.formatted-version} :: +${Ansi.DEFAULT} \ No newline at end of file diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/keystore.p12 b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..e6998da14a2a2304fff438dae664670aece8815f GIT binary patch literal 6250 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 literal 0 HcmV?d00001 diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/truststore.p12 b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/truststore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..65dfaa50d318c764a91566ab989f821608541eb9 GIT binary patch literal 1927 zcmV;22YC1}f(L^F0Ru3C2RsG|Duzgg_YDCD0ic2hEd+uGDKLTuB`|^qAqEL5hDe6@ z4FLxRpn?YyFoFjT0s#Opf(Hi%2`Yw2hW8Bt2LUi<1_>&LNQU+thDZTr0|Wso1Q2n-=4e0Z;~}9Vg}{agmROQh|+5_y~Qf5;#X-699JFY`E5~^{pdY+KfOqu>RZBsGPf`@PCD1cH2#k`CRAI0@4v*}&!h*axa`kZ5` z^|sp4Gs9{O<8>`aAboJ(8H6g==;h>jkk?aHR_fi-66ayag(pEg1;2aJpGQgh25OqZ z++g?$+hkoSjtU3q?AgA6k4KZ%EhIjQ5XUNLyA;45#G{{;3x>1Fm3P50wo}$3=ufj8 z>s`a?C7d@i6_RccN*QPokg#c;%#zwP_C}!^yC(IDhF?v=x2-cFy*E5?QqVGY=qNn1 z^-Kps=hHWp@b3Rbn?p}Oxg4I5)Pk*0UZNHQiRK1#=m8e9#)f*a>_JnUB{B6mvTBu)D8-O9-gw$Jk}z$ zFrQu>w&mne;mwcLY3?h;JXV9u@g%;J0OMf;F*nG6Kx0riv@BSGrW^C&ZO%5u!|zgd z*QqRc0gGvOi6F1FNI$XTnwD!2>6cORSW?>ulfk}~Bw22!y6!tUNi-0#^$QQ6^7H0c%4BIigytxan;{04ZF`=IR9)S^5ZT%jkb+-tAVc0NwQiXC=opVH)G2Cr2Eg_==G^iKdixoTJGscjLd>JXS3YSrkYUA* zOL+h^Bx9RI7r%!2ZRa9sJcW6JjT$axIyvYuZALdkgwJIa;D78-7_CA-pFHN+oF%S8 zjDY@WVtj3FJ}@=Q{=UuP%u|g8tSTZm9X~68r)zBD zV^;^A-rwIVwXF8V_?;3~#aH&%N52x&KII1-?4gbSp`%;WXLF%02(~UK<6F*WgApD<=C?ZX!;1d%l7Q0x#FtYKxVBMW{k8Mbd(CzAqeoM zh0NXrG<6MA`-J$r%P0M^&XDCFs{6r;N$XCSKj?eTkQ+9%gDx1SHE~OCe5H${open-metadata.version} + + org.odpi.egeria + server-standalone-spring + compile + ${open-metadata.version} + + org.odpi.egeria open-lineage-janus-connector diff --git a/settings.gradle b/settings.gradle index a7481754935..a22687dc44d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -807,6 +807,8 @@ project(':open-metadata-implementation:platform-services:platform-services-sprin project(':open-metadata-implementation:platform-services').projectDir = file('open-metadata-implementation/platform-services') project(':open-metadata-implementation:server-chassis:server-chassis-spring').projectDir = file('open-metadata-implementation/server-chassis/server-chassis-spring') project(':open-metadata-implementation:server-chassis').projectDir = file('open-metadata-implementation/server-chassis') +project(':open-metadata-implementation:server-standalone:server-standalone-spring').projectDir = file('open-metadata-implementation/server-standalone/server-standalone-spring') +project(':open-metadata-implementation:server-standalone').projectDir = file('open-metadata-implementation/server-standalone') project(':open-metadata-implementation:user-interfaces:ui-chassis:ui-chassis-spring').projectDir = file('open-metadata-implementation/user-interfaces/ui-chassis/ui-chassis-spring') project(':open-metadata-implementation:user-interfaces:ui-chassis').projectDir = file('open-metadata-implementation/user-interfaces/ui-chassis') project(':open-metadata-implementation:user-interfaces').projectDir = file('open-metadata-implementation/user-interfaces') From a128270faf788d187de9217fd0059b853f43927b Mon Sep 17 00:00:00 2001 From: David Radley Date: Fri, 10 Mar 2023 13:13:52 +0000 Subject: [PATCH 2/5] git7512 rename Signed-off-by: David Radley --- ...AGServerPlatform.java => StandaloneOMAGServer.java} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/{OMAGServerPlatform.java => StandaloneOMAGServer.java} (94%) diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java similarity index 94% rename from open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java rename to open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java index 691c34594ee..2efc4e3f376 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerPlatform.java +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 */ /* Copyright Contributors to the ODPi Egeria project. */ -package main.java.org.odpi.openmetadata.serverstandalone.springboot; +package org.odpi.openmetadata.serverstandalone.springboot; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.OpenAPIDefinition; @@ -68,7 +68,7 @@ @Configuration -public class OMAGServerPlatform +public class StandaloneOMAGServer { @Value("${strict.ssl}") Boolean strictSSL; @@ -92,10 +92,10 @@ public class OMAGServerPlatform private String startupMessage = ""; private OMAGServerOperationalServices operationalServices = new OMAGServerOperationalServices(); - private static final Logger log = LoggerFactory.getLogger(OMAGServerPlatform.class); + private static final Logger log = LoggerFactory.getLogger(main.java.org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class); public static void main(String[] args) { - SpringApplication.run(OMAGServerPlatform.class, args); + SpringApplication.run(main.java.org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class, args); } @Bean @@ -192,7 +192,7 @@ public class ApplicationContextListener @EventListener(ApplicationReadyEvent.class) public void applicationReady() { autoStartConfig(); - System.out.println(OMAGServerPlatform.this.startupMessage); + System.out.println(main.java.org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.this.startupMessage); if(triggeredRuntimeHalt){ Runtime.getRuntime().halt(43); From 0a3b20887b0823386d6fc1f4441e74b165cba677 Mon Sep 17 00:00:00 2001 From: David Radley Date: Fri, 10 Mar 2023 16:06:40 +0000 Subject: [PATCH 3/5] git7512 initial application Signed-off-by: David Radley --- .../server/OMAGServerOperationalServices.java | 450 ++++++++++++++++++ .../server-standalone-spring/build.gradle | 7 +- .../springboot/StandaloneOMAGServer.java | 51 +- .../src/main/resources/banner.txt | 16 +- settings.gradle | 2 + 5 files changed, 484 insertions(+), 42 deletions(-) diff --git a/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java b/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java index f655ec72141..37aafe60a78 100644 --- a/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java +++ b/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java @@ -168,6 +168,456 @@ public SuccessMessageResponse activateWithStoredConfig(String userId, return response; } + /** + * Activate the open metadata and governance services using the supplied configuration + * document. Inside the configuration document are sections that each relate + * to an open metadata and governance subsystem. This method reads the configuration + * document, starting up each requested subsystem. If any subsystem throws an exception, + * the whole start up process is halted and the exception is returned to the caller. + * + * @param userId user that is issuing the request + * @param configuration properties used to initialize the services + * @return success message response or + * OMAGNotAuthorizedException the supplied userId is not authorized to issue this command or + * OMAGInvalidParameterException the server name is invalid or + * OMAGConfigurationErrorException there is a problem using the supplied configuration. + */ + public SuccessMessageResponse activateServerWithSuppliedConfig(String userId, + OMAGServerConfig configuration) + { + final String methodName = "activateServerWithSuppliedConfig"; + final String actionDescription = "Initialize OMAG standalone Server subsystems"; + RESTCallToken token = null; + + + List activatedServiceList = new ArrayList<>(); + OMAGOperationalServicesInstance instance = null; + SuccessMessageResponse response = new SuccessMessageResponse(); + + String serverName =configuration.getLocalServerName(); + + try + { + /* + * Check that a serverName and userId is supplied + */ + token = restCallLogger.logRESTCall(serverName, userId, methodName); + errorHandler.validateServerName(serverName, methodName); + errorHandler.validateUserId(userId, serverName, methodName); + + + /* + * Validate the content of the configuration document. This will throw an exception if the + * configuration document is null or the combination of requested services does not make a useful server. + */ + ServerTypeClassifier serverTypeClassifier = new ServerTypeClassifier(serverName, configuration); + ServerTypeClassification serverTypeClassification = serverTypeClassifier.getServerType(); + + /* + * If the server type is not set then use the value from the classification. + */ + if (configuration.getLocalServerType() == null) + { + configuration.setLocalServerType(serverTypeClassification.getServerTypeName()); + } + + /* + * Save the configuration document to the config store. This ensures we have the latest version of the + * config document on file. + */ +// configStore.saveServerConfig(serverName, methodName, configuration); + + /* + * Validate that the server is not running already. If it is running it should be shutdown. + */ +// if (instanceHandler.isServerActive(userId, serverName)) +// { +// this.deactivateTemporarily(userId, serverName); +// } + + /* + * The instance saves the operational services objects for this server instance so they can be retrieved + * in response to subsequent REST calls for the server. These instances provide the multi-tenant + * support in Egeria. + */ + instance = new OMAGOperationalServicesInstance(serverName, + serverTypeClassification, + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceName(), + configuration.getMaxPageSize()); + instance.setServerActiveStatus(ServerActiveStatus.STARTING); + + /* + * Save the configuration that is going to be used to start the server for this instance. This configuration can be queried by + * the operator to verify the configuration used to start the server. (The values in the config store may have been + * updated since the server was started.) + */ + instance.setOperationalConfiguration(configuration); + + /* ================================ + * Ready to start subsystems. A failure in startup for any subsystem is fatal. + */ + + /* + * Initialize the open metadata repository services first since other services depend on it. + * (Even the governance servers need the audit log.) + */ + OMRSOperationalServices operationalRepositoryServices; + + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.STARTING); + operationalRepositoryServices = new OMRSOperationalServices(configuration.getLocalServerName(), + configuration.getLocalServerType(), + configuration.getOrganizationName(), + configuration.getLocalServerUserId(), + configuration.getLocalServerPassword(), + configuration.getLocalServerURL(), + configuration.getMaxPageSize()); + activatedServiceList.add(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName()); + operationalRepositoryServices.initializeAuditLog(configuration.getRepositoryServicesConfig(), + serverTypeClassification.getServerTypeName()); + + + + /* + * Create an audit log for logging initialization progress and errors. + * Each subsystem should be logging the start up of their components and handling + * their errors. However the logging and error handling done by this method is to bracket the + * start up of the different types of subsystems and provide minimal diagnostics for + * immature subsystems that have not yet developed their logging and error handling. + */ + OMRSAuditLog auditLog = operationalRepositoryServices.getAuditLog( + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceCode(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceDevelopmentStatus(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceName(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceDescription(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceWiki()); + instance.setAuditLog(auditLog); + + /* + * There are many paging services in Egeria. This value sets a maximum page size that a requester can use. + * It is passed to each subsystem at start up so it can enforce the limit on all paging REST calls. + * Having a limit helps to prevent a denial of service attack that uses very large requests to overwhelm the server. + * If this value is 0 it means there is no upper limit. If this value is negative then it is invalid. + */ + this.validateMaxPageSize(configuration.getMaxPageSize(), serverName, auditLog, methodName); + + /* + * Save the instance of the repository services and then initialize it. OMRS has 2 modes of initialization. + * Firstly for a basic server such as a governance server, just the audit log is initialized. + * For a metadata server, repository proxy and conformance test server, initialization will optionally set up the + * connector to the local repository, initialize the enterprise repository services (used by + * the access services and conformance test server) and connect to the server's cohorts. It is controlled by the settings in the + * repository services configuration document. The repository services instance is saved since it needs to be called for shutdown. + */ + instance.setOperationalRepositoryServices(operationalRepositoryServices); + + /* + * At this point the type of server influences the start-up sequence. + */ + if ((ServerTypeClassification.METADATA_SERVER.equals(serverTypeClassification)) || + (ServerTypeClassification.METADATA_ACCESS_POINT.equals(serverTypeClassification)) || + (ServerTypeClassification.REPOSITORY_PROXY.equals(serverTypeClassification)) || + (ServerTypeClassification.CONFORMANCE_SERVER.equals(serverTypeClassification))) + { + /* + * This server is a source of metadata and is capable of joining an open metadata repository cohort. + */ + operationalRepositoryServices.initializeCohortMember(configuration.getRepositoryServicesConfig()); + + /* + * Set up the server instance - ensure it is active and the security has been set up correctly. + */ + OpenMetadataServerSecurityVerifier securityVerifier = + platformInstanceMap.startUpServerInstance(configuration.getLocalServerUserId(), + serverName, + operationalRepositoryServices.getAuditLog(CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceCode(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDevelopmentStatus(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceName(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDescription(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceWiki()), + configuration.getServerSecurityConnection()); + + /* + * Pass the resulting security verifier to the repository services. It will be set up in the local + * repository (if there is a local repository in this server). This is the point where we connect to the cohort. + */ + operationalRepositoryServices.setSecurityVerifier(securityVerifier); + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.RUNNING); + + /* + * Next initialize the Open Connector Framework (OCF) metadata services. These services are only initialized + * if the enterprise repository services are enabled. They support requests for metadata from connectors running + * outside the metadata server. + */ + OMRSRepositoryConnector enterpriseRepositoryConnector + = operationalRepositoryServices.getEnterpriseOMRSRepositoryConnector(CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName()); + + if (enterpriseRepositoryConnector != null) + { + /* + * The enterprise repository services have been requested so OCF metadata management can be started. + */ + OCFMetadataOperationalServices operationalOCFMetadataServices; + + instance.setServerServiceActiveStatus(CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName(), ServerActiveStatus.STARTING); + operationalOCFMetadataServices = new OCFMetadataOperationalServices(configuration.getLocalServerName(), + enterpriseRepositoryConnector, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceCode(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceDevelopmentStatus(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceDescription(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceWiki()), + configuration.getLocalServerUserId(), + configuration.getMaxPageSize()); + + instance.setOperationalOCFMetadataServices(operationalOCFMetadataServices); + activatedServiceList.add(CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName()); + + /* + * The enterprise repository services have been requested so GAF metadata management can also be started. + */ + GAFMetadataOperationalServices operationalGAFMetadataServices; + + instance.setServerServiceActiveStatus(CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceName(), ServerActiveStatus.STARTING); + operationalGAFMetadataServices = new GAFMetadataOperationalServices(configuration.getLocalServerName(), + enterpriseRepositoryConnector, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceCode(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceDevelopmentStatus(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceName(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceDescription(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceWiki()), + configuration.getLocalServerUserId(), + configuration.getMaxPageSize()); + + instance.setOperationalGAFMetadataServices(operationalGAFMetadataServices); + activatedServiceList.add(CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceName()); + } + + /* + * Now initialize the configured open metadata access services. Each access service has its own subsystem. It is + * initialized via an Admin object that controls its start up and shutdown. The configuration service just needs to create the + * appropriate admin object (specified in the configuration) and initialize it with its own configuration + * document. The admin object then does the rest. The admin objects are stored in the instance since + * they also need to be called for shutdown. + * + * Each access service is given access to the events from open metadata repository cohorts that this server connects to. + * The enterprise topic connector supplies these events. The access service registers a listener with it to receive them. + */ + OMRSTopicConnector enterpriseTopicConnector = operationalRepositoryServices.getEnterpriseOMRSTopicConnector(); + + initializeAccessServices(instance, + configuration.getAccessServicesConfig(), + operationalRepositoryServices, + enterpriseTopicConnector, + configuration.getLocalServerUserId(), + serverName, + activatedServiceList, + auditLog); + + /* + * Initialize the Open Metadata Conformance Suite Services. This runs the Open Metadata TestLabs that are + * part of the ODPi Egeria Conformance Program. + */ + if (ServerTypeClassification.CONFORMANCE_SERVER.equals(serverTypeClassification)) + { + ConformanceSuiteOperationalServices + operationalConformanceSuiteServices = new ConformanceSuiteOperationalServices(configuration.getLocalServerName(), + configuration.getLocalServerUserId(), + configuration.getLocalServerPassword(), + configuration.getMaxPageSize()); + instance.setOperationalConformanceSuiteServices(operationalConformanceSuiteServices); + operationalConformanceSuiteServices.initialize(configuration.getConformanceSuiteConfig(), + enterpriseTopicConnector, + operationalRepositoryServices.getEnterpriseConnectorManager(), + operationalRepositoryServices.getAuditLog( + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceCode(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceDevelopmentStatus(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceName(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceDescription(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceWiki())); + + activatedServiceList.add(GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceName()); + } + + /* + * The enterprise topic passes OMRS Events from the cohort to the listening access services. + * During the access services start up, they registered listeners with the enterprise topic. + * Starting the enterprise topic will start the flow of events to the registered access services. + */ + if (enterpriseTopicConnector != null) + { + try + { + enterpriseTopicConnector.start(); + } + catch (Exception error) + { + throw new OMAGConfigurationErrorException(OMAGAdminErrorCode.ENTERPRISE_TOPIC_START_FAILED.getMessageDefinition(serverName, + "in memory", + error.getClass().getName(), + error.getMessage()), + this.getClass().getName(), + methodName); + } + } + } + + else if (ServerTypeClassification.VIEW_SERVER.equals(serverTypeClassification)) + { + /* + * Set up the repository services REST API + */ + operationalRepositoryServices.initializeViewServer(configuration.getRepositoryServicesConfig()); + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.RUNNING); + + /* + * Set up the server instance - ensure it is active and the security has been set up correctly. + */ + platformInstanceMap.startUpServerInstance(configuration.getLocalServerUserId(), + serverName, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceCode(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDevelopmentStatus(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceName(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDescription(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceWiki()), + configuration.getServerSecurityConnection()); + + + /* + * Set up the view services that are the speciality of the view server. + */ + initializeViewServices(instance, + configuration.getViewServicesConfig(), + operationalRepositoryServices, + configuration.getLocalServerUserId(), + serverName, + activatedServiceList, + configuration.getMaxPageSize(), + auditLog); + } + else /* governance servers */ + { + /* + * Set up the repository services REST API + */ + operationalRepositoryServices.initializeGovernanceServer(configuration.getRepositoryServicesConfig()); + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.RUNNING); + + /* + * Governance servers are varied in nature. Many host connectors that exchange metadata with third party technologies. + * However they may also host specific types of engines, or provide an implementation of a complete governance service. + * Because of this variety, Egeria does not (yet) provide any specialist frameworks for supporting the governance servers. + * all the implementation is in the governance services subsystems initialized below. + * + * Set up the server instance - ensure it is active and the security has been set up correctly. + */ + platformInstanceMap.startUpServerInstance(configuration.getLocalServerUserId(), + serverName, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceCode(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDevelopmentStatus(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceName(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDescription(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceWiki()), + configuration.getServerSecurityConnection()); + + + /* + * Start up the governance services subsystem. Each type of governance server has its own type of governance services + * subsystem. Each is responsible for handling its own errors. The error handling that follows helps to position + * where any issues are occurring. + */ + try + { + auditLog.logMessage(actionDescription, + OMAGAdminAuditCode.STARTING_GOVERNANCE_SERVICES.getMessageDefinition(serverTypeClassifier.getServerType().getServerTypeName(), + serverName)); + + initializeGovernanceServices(instance, + configuration, + serverTypeClassification, + operationalRepositoryServices, + activatedServiceList); + + auditLog.logMessage(actionDescription, + OMAGAdminAuditCode.GOVERNANCE_SERVICES_STARTED.getMessageDefinition(serverTypeClassifier.getServerType().getServerTypeName(), + serverName)); + } + catch (OMAGConfigurationErrorException error) + { + /* + * There is a configuration error that means that the governance services subsystem can not start. Since this is + * the primary function of the server then there is no purpose in continuing. + */ + auditLog.logException(actionDescription, + OMAGAdminAuditCode.GOVERNANCE_SERVICE_FAILURE.getMessageDefinition(error.getClass().getName(), + serverTypeClassifier.getServerType().getServerTypeName(), + serverName, + error.getReportedErrorMessage()), + error); + throw error; + } + catch (Exception error) + { + /* + * Uncontrolled error from the governance service subsystem. The subsystem could be in any state. + * Capture additional information about the error and stop the server startup. + */ + auditLog.logException(actionDescription, + OMAGAdminAuditCode.GOVERNANCE_SERVICE_FAILURE.getMessageDefinition(error.getClass().getName(), + serverTypeClassifier.getServerType().getServerTypeName(), + serverName, + error.getMessage()), + error); + throw error; + } + } + + /* + * All subsystems are started - just log messages and return. + */ + instance.setServerActiveStatus(ServerActiveStatus.RUNNING); + + String successMessage = new Date().toString() + " " + serverName + " is running the following services: " + activatedServiceList.toString(); + + auditLog.logMessage(actionDescription, + OMAGAdminAuditCode.SERVER_STARTUP_SUCCESS.getMessageDefinition(serverName, + activatedServiceList.toString())); + + response.setSuccessMessage(successMessage); + } +// catch (UserNotAuthorizedException error) +// { +// exceptionHandler.captureNotAuthorizedException(response, error); +// cleanUpRunningServiceInstances(userId, serverName, methodName, instance); +// } + catch (OMAGConfigurationErrorException error) + { + exceptionHandler.captureConfigurationErrorException(response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + catch (OMAGInvalidParameterException error) + { + exceptionHandler.captureInvalidParameterException(response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + catch (OMAGNotAuthorizedException error) + { + exceptionHandler.captureNotAuthorizedException(response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + catch (Exception error) + { + exceptionHandler.capturePlatformRuntimeException(serverName, methodName, response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + + restCallLogger.logRESTCallReturn(token, response.toString()); + return response; + } + /** * Activate the open metadata and governance services using the supplied configuration diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle index 8e517a72fb7..8c4eacc4baa 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle @@ -33,9 +33,9 @@ dependencies { implementation 'org.springframework:spring-beans' implementation 'org.springframework:spring-core' implementation 'org.springframework:spring-context' - + implementation project(':open-metadata-implementation:admin-services:admin-services-server') compileOnly project(':open-metadata-implementation:common-services:ffdc-services') - + implementation project(':open-metadata-implementation:admin-services:admin-services-api') runtimeOnly 'ch.qos.logback:logback-classic' implementation project(':open-metadata-implementation:adapters:authentication-plugins:http-helper') implementation 'org.slf4j:slf4j-api' @@ -43,6 +43,7 @@ dependencies { implementation 'io.swagger.core.v3:swagger-annotations' runtimeOnly 'org.hibernate:hibernate-validator' runtimeOnly project(':open-metadata-implementation:platform-services:platform-services-spring') + runtimeOnly project(':open-metadata-implementation:admin-services:admin-services-spring') // The following are only included at runtime for the full platform (ie adminChassisOnly is not set as a property) if (!project.hasProperty("adminChassisOnly")) { @@ -105,7 +106,7 @@ dependencies { } } -description = 'OMAG Server Platform with standalone server for Spring' +description = 'OMAG Server Platform Chassis for Spring' bootJar { manifest { diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java index 2efc4e3f376..76dc787237f 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java @@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.info.License; +import org.odpi.openmetadata.adminservices.configuration.properties.OMAGServerConfig; import org.odpi.openmetadata.adminservices.server.OMAGServerOperationalServices; import org.odpi.openmetadata.adminservices.rest.SuccessMessageResponse; import org.odpi.openmetadata.http.HttpHelper; @@ -92,10 +93,10 @@ public class StandaloneOMAGServer private String startupMessage = ""; private OMAGServerOperationalServices operationalServices = new OMAGServerOperationalServices(); - private static final Logger log = LoggerFactory.getLogger(main.java.org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class); + private static final Logger log = LoggerFactory.getLogger(org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class); public static void main(String[] args) { - SpringApplication.run(main.java.org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class, args); + SpringApplication.run(org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class, args); } @Bean @@ -140,19 +141,17 @@ List getAutoStartList() } /** - * Starts the servers specified in the startup.server.list property + * Starts the server in the supplied configuration */ - private void autoStartConfig() + private void startServer() { - List servers = getAutoStartList(); - - if (servers != null) - { - log.info("Startup detected for servers: {}", startupServers); - } - - SuccessMessageResponse response = operationalServices.activateServerListWithStoredConfig(sysUser.trim(), servers); - +// if (servers != null) +// { +// log.info("Startup detected for servers: {}", startupServers); +// } + OMAGServerConfig configuration = null; + String userId = "garygeeke"; + SuccessMessageResponse response = operationalServices.activateServerWithSuppliedConfig(userId, configuration); if (response.getRelatedHTTPCode() == 200) { startupMessage = response.getSuccessMessage(); @@ -168,22 +167,6 @@ private void autoStartConfig() } - /** - * Deactivate all servers that were started automatically - */ - private void temporaryDeactivateServers() - { - List servers = getAutoStartList(); - - if (servers != null) - { - log.info("Temporarily deactivating any auto-started servers '{}'", servers); - - System.out.println(new Date() + " OMAG Server Platform shutdown requested. Shutting down auto-started servers (if running): " + servers); - - operationalServices.deactivateTemporarilyServerList(sysUser, servers); - } - } @Component public class ApplicationContextListener @@ -191,8 +174,8 @@ public class ApplicationContextListener @EventListener(ApplicationReadyEvent.class) public void applicationReady() { - autoStartConfig(); - System.out.println(main.java.org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.this.startupMessage); + startServer(); + System.out.println(org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.this.startupMessage); if(triggeredRuntimeHalt){ Runtime.getRuntime().halt(43); @@ -203,7 +186,8 @@ public void applicationReady() { @EventListener public void onApplicationEvent(ContextClosedEvent event) { - temporaryDeactivateServers(); +// temporaryDeactivateServers(); + //TODO should we do anything here ? } } @@ -213,7 +197,8 @@ public class CustomSpringEventListener implements ApplicationListener Date: Mon, 13 Mar 2023 17:03:01 +0000 Subject: [PATCH 4/5] git7512 initial prototype Signed-off-by: David Radley --- .../server/OMAGServerOperationalServices.java | 447 ++++++++++++++++++ .../server-standalone/pom.xml | 6 +- .../server-standalone-spring/build.gradle | 3 +- .../server-standalone-spring/pom.xml | 18 +- ...GServer.java => OMAGServerStandalone.java} | 109 +++-- .../src/main/resources/application.properties | 4 +- .../src/main/resources/banner.txt | 16 +- 7 files changed, 536 insertions(+), 67 deletions(-) rename open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/{StandaloneOMAGServer.java => OMAGServerStandalone.java} (75%) diff --git a/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java b/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java index 37aafe60a78..ced49c65d6c 100644 --- a/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java +++ b/open-metadata-implementation/admin-services/admin-services-server/src/main/java/org/odpi/openmetadata/adminservices/server/OMAGServerOperationalServices.java @@ -1067,6 +1067,453 @@ else if (ServerTypeClassification.VIEW_SERVER.equals(serverTypeClassification)) return response; } + /** + * Activate the open metadata and governance services using the supplied configuration + * document. Inside the configuration document are sections that each relate + * to an open metadata and governance subsystem. This method reads the configuration + * document, starting up each requested subsystem. If any subsystem throws an exception, + * the whole start up process is halted and the exception is returned to the caller. + * + * @param userId user that is issuing the request + * @param configuration properties used to initialize the services + * @return success message response or + * OMAGNotAuthorizedException the supplied userId is not authorized to issue this command or + * OMAGInvalidParameterException the server name is invalid or + * OMAGConfigurationErrorException there is a problem using the supplied configuration. + */ + public SuccessMessageResponse activateWithSuppliedConfig(String userId, + OMAGServerConfig configuration) + { + final String methodName = "activateWithSuppliedConfig"; + final String actionDescription = "Initialize OMAG Server subsystems"; + String serverName = configuration.getLocalServerName(); + + RESTCallToken token = restCallLogger.logRESTCall(serverName, userId, methodName); + + List activatedServiceList = new ArrayList<>(); + OMAGOperationalServicesInstance instance = null; + SuccessMessageResponse response = new SuccessMessageResponse(); + + try + { + /* + * Check that a serverName and userId is supplied + */ + errorHandler.validateServerName(serverName, methodName); + errorHandler.validateUserId(userId, serverName, methodName); + + /* + * Validate the content of the configuration document. This will throw an exception if the + * configuration document is null or the combination of requested services does not make a useful server. + */ + ServerTypeClassifier serverTypeClassifier = new ServerTypeClassifier(serverName, configuration); + ServerTypeClassification serverTypeClassification = serverTypeClassifier.getServerType(); + + /* + * If the server type is not set then use the value from the classification. + */ + if (configuration.getLocalServerType() == null) + { + configuration.setLocalServerType(serverTypeClassification.getServerTypeName()); + } + + /* + * Save the configuration document to the config store. This ensures we have the latest version of the + * config document on file. + */ +// configStore.saveServerConfig(serverName, methodName, configuration); + + /* + * Validate that the server is not running already. If it is running it should be shutdown. + */ +// if (instanceHandler.isServerActive(userId, serverName)) +// { +// this.deactivateTemporarily(userId, serverName); +// } + + /* + * The instance saves the operational services objects for this server instance so they can be retrieved + * in response to subsequent REST calls for the server. These instances provide the multi-tenant + * support in Egeria. + */ + instance = new OMAGOperationalServicesInstance(serverName, + serverTypeClassification, + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceName(), + configuration.getMaxPageSize()); + instance.setServerActiveStatus(ServerActiveStatus.STARTING); + + /* + * Save the configuration that is going to be used to start the server for this instance. This configuration can be queried by + * the operator to verify the configuration used to start the server. (The values in the config store may have been + * updated since the server was started.) + */ + instance.setOperationalConfiguration(configuration); + + /* ================================ + * Ready to start subsystems. A failure in startup for any subsystem is fatal. + */ + + /* + * Initialize the open metadata repository services first since other services depend on it. + * (Even the governance servers need the audit log.) + */ + OMRSOperationalServices operationalRepositoryServices; + + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.STARTING); + operationalRepositoryServices = new OMRSOperationalServices(configuration.getLocalServerName(), + configuration.getLocalServerType(), + configuration.getOrganizationName(), + configuration.getLocalServerUserId(), + configuration.getLocalServerPassword(), + configuration.getLocalServerURL(), + configuration.getMaxPageSize()); + activatedServiceList.add(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName()); + operationalRepositoryServices.initializeAuditLog(configuration.getRepositoryServicesConfig(), + serverTypeClassification.getServerTypeName()); + + + + /* + * Create an audit log for logging initialization progress and errors. + * Each subsystem should be logging the start up of their components and handling + * their errors. However the logging and error handling done by this method is to bracket the + * start up of the different types of subsystems and provide minimal diagnostics for + * immature subsystems that have not yet developed their logging and error handling. + */ + OMRSAuditLog auditLog = operationalRepositoryServices.getAuditLog( + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceCode(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceDevelopmentStatus(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceName(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceDescription(), + CommonServicesDescription.ADMIN_OPERATIONAL_SERVICES.getServiceWiki()); + instance.setAuditLog(auditLog); + + /* + * There are many paging services in Egeria. This value sets a maximum page size that a requester can use. + * It is passed to each subsystem at start up so it can enforce the limit on all paging REST calls. + * Having a limit helps to prevent a denial of service attack that uses very large requests to overwhelm the server. + * If this value is 0 it means there is no upper limit. If this value is negative then it is invalid. + */ + this.validateMaxPageSize(configuration.getMaxPageSize(), serverName, auditLog, methodName); + + /* + * Save the instance of the repository services and then initialize it. OMRS has 2 modes of initialization. + * Firstly for a basic server such as a governance server, just the audit log is initialized. + * For a metadata server, repository proxy and conformance test server, initialization will optionally set up the + * connector to the local repository, initialize the enterprise repository services (used by + * the access services and conformance test server) and connect to the server's cohorts. It is controlled by the settings in the + * repository services configuration document. The repository services instance is saved since it needs to be called for shutdown. + */ + instance.setOperationalRepositoryServices(operationalRepositoryServices); + + /* + * At this point the type of server influences the start-up sequence. + */ + if ((ServerTypeClassification.METADATA_SERVER.equals(serverTypeClassification)) || + (ServerTypeClassification.METADATA_ACCESS_POINT.equals(serverTypeClassification)) || + (ServerTypeClassification.REPOSITORY_PROXY.equals(serverTypeClassification)) || + (ServerTypeClassification.CONFORMANCE_SERVER.equals(serverTypeClassification))) + { + /* + * This server is a source of metadata and is capable of joining an open metadata repository cohort. + */ + operationalRepositoryServices.initializeCohortMember(configuration.getRepositoryServicesConfig()); + + /* + * Set up the server instance - ensure it is active and the security has been set up correctly. + */ + OpenMetadataServerSecurityVerifier securityVerifier = + platformInstanceMap.startUpServerInstance(configuration.getLocalServerUserId(), + serverName, + operationalRepositoryServices.getAuditLog(CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceCode(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDevelopmentStatus(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceName(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDescription(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceWiki()), + configuration.getServerSecurityConnection()); + + /* + * Pass the resulting security verifier to the repository services. It will be set up in the local + * repository (if there is a local repository in this server). This is the point where we connect to the cohort. + */ + operationalRepositoryServices.setSecurityVerifier(securityVerifier); + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.RUNNING); + + /* + * Next initialize the Open Connector Framework (OCF) metadata services. These services are only initialized + * if the enterprise repository services are enabled. They support requests for metadata from connectors running + * outside the metadata server. + */ + OMRSRepositoryConnector enterpriseRepositoryConnector + = operationalRepositoryServices.getEnterpriseOMRSRepositoryConnector(CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName()); + + if (enterpriseRepositoryConnector != null) + { + /* + * The enterprise repository services have been requested so OCF metadata management can be started. + */ + OCFMetadataOperationalServices operationalOCFMetadataServices; + + instance.setServerServiceActiveStatus(CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName(), ServerActiveStatus.STARTING); + operationalOCFMetadataServices = new OCFMetadataOperationalServices(configuration.getLocalServerName(), + enterpriseRepositoryConnector, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceCode(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceDevelopmentStatus(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceDescription(), + CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceWiki()), + configuration.getLocalServerUserId(), + configuration.getMaxPageSize()); + + instance.setOperationalOCFMetadataServices(operationalOCFMetadataServices); + activatedServiceList.add(CommonServicesDescription.OCF_METADATA_MANAGEMENT.getServiceName()); + + /* + * The enterprise repository services have been requested so GAF metadata management can also be started. + */ + GAFMetadataOperationalServices operationalGAFMetadataServices; + + instance.setServerServiceActiveStatus(CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceName(), ServerActiveStatus.STARTING); + operationalGAFMetadataServices = new GAFMetadataOperationalServices(configuration.getLocalServerName(), + enterpriseRepositoryConnector, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceCode(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceDevelopmentStatus(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceName(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceDescription(), + CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceWiki()), + configuration.getLocalServerUserId(), + configuration.getMaxPageSize()); + + instance.setOperationalGAFMetadataServices(operationalGAFMetadataServices); + activatedServiceList.add(CommonServicesDescription.GAF_METADATA_MANAGEMENT.getServiceName()); + } + + /* + * Now initialize the configured open metadata access services. Each access service has its own subsystem. It is + * initialized via an Admin object that controls its start up and shutdown. The configuration service just needs to create the + * appropriate admin object (specified in the configuration) and initialize it with its own configuration + * document. The admin object then does the rest. The admin objects are stored in the instance since + * they also need to be called for shutdown. + * + * Each access service is given access to the events from open metadata repository cohorts that this server connects to. + * The enterprise topic connector supplies these events. The access service registers a listener with it to receive them. + */ + OMRSTopicConnector enterpriseTopicConnector = operationalRepositoryServices.getEnterpriseOMRSTopicConnector(); + + initializeAccessServices(instance, + configuration.getAccessServicesConfig(), + operationalRepositoryServices, + enterpriseTopicConnector, + configuration.getLocalServerUserId(), + serverName, + activatedServiceList, + auditLog); + + /* + * Initialize the Open Metadata Conformance Suite Services. This runs the Open Metadata TestLabs that are + * part of the ODPi Egeria Conformance Program. + */ + if (ServerTypeClassification.CONFORMANCE_SERVER.equals(serverTypeClassification)) + { + ConformanceSuiteOperationalServices + operationalConformanceSuiteServices = new ConformanceSuiteOperationalServices(configuration.getLocalServerName(), + configuration.getLocalServerUserId(), + configuration.getLocalServerPassword(), + configuration.getMaxPageSize()); + instance.setOperationalConformanceSuiteServices(operationalConformanceSuiteServices); + operationalConformanceSuiteServices.initialize(configuration.getConformanceSuiteConfig(), + enterpriseTopicConnector, + operationalRepositoryServices.getEnterpriseConnectorManager(), + operationalRepositoryServices.getAuditLog( + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceCode(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceDevelopmentStatus(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceName(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceDescription(), + GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceWiki())); + + activatedServiceList.add(GovernanceServicesDescription.CONFORMANCE_SUITE_SERVICES.getServiceName()); + } + + /* + * The enterprise topic passes OMRS Events from the cohort to the listening access services. + * During the access services start up, they registered listeners with the enterprise topic. + * Starting the enterprise topic will start the flow of events to the registered access services. + */ + if (enterpriseTopicConnector != null) + { + try + { + enterpriseTopicConnector.start(); + } + catch (Exception error) + { + throw new OMAGConfigurationErrorException(OMAGAdminErrorCode.ENTERPRISE_TOPIC_START_FAILED.getMessageDefinition(serverName, + "in memory", + error.getClass().getName(), + error.getMessage()), + this.getClass().getName(), + methodName); + } + } + } + + else if (ServerTypeClassification.VIEW_SERVER.equals(serverTypeClassification)) + { + /* + * Set up the repository services REST API + */ + operationalRepositoryServices.initializeViewServer(configuration.getRepositoryServicesConfig()); + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.RUNNING); + + /* + * Set up the server instance - ensure it is active and the security has been set up correctly. + */ + platformInstanceMap.startUpServerInstance(configuration.getLocalServerUserId(), + serverName, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceCode(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDevelopmentStatus(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceName(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDescription(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceWiki()), + configuration.getServerSecurityConnection()); + + + /* + * Set up the view services that are the speciality of the view server. + */ + initializeViewServices(instance, + configuration.getViewServicesConfig(), + operationalRepositoryServices, + configuration.getLocalServerUserId(), + serverName, + activatedServiceList, + configuration.getMaxPageSize(), + auditLog); + } + else /* governance servers */ + { + /* + * Set up the repository services REST API + */ + operationalRepositoryServices.initializeGovernanceServer(configuration.getRepositoryServicesConfig()); + instance.setServerServiceActiveStatus(CommonServicesDescription.REPOSITORY_SERVICES.getServiceName(), ServerActiveStatus.RUNNING); + + /* + * Governance servers are varied in nature. Many host connectors that exchange metadata with third party technologies. + * However they may also host specific types of engines, or provide an implementation of a complete governance service. + * Because of this variety, Egeria does not (yet) provide any specialist frameworks for supporting the governance servers. + * all the implementation is in the governance services subsystems initialized below. + * + * Set up the server instance - ensure it is active and the security has been set up correctly. + */ + platformInstanceMap.startUpServerInstance(configuration.getLocalServerUserId(), + serverName, + operationalRepositoryServices.getAuditLog( + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceCode(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDevelopmentStatus(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceName(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceDescription(), + CommonServicesDescription.OPEN_METADATA_SECURITY.getServiceWiki()), + configuration.getServerSecurityConnection()); + + + /* + * Start up the governance services subsystem. Each type of governance server has its own type of governance services + * subsystem. Each is responsible for handling its own errors. The error handling that follows helps to position + * where any issues are occurring. + */ + try + { + auditLog.logMessage(actionDescription, + OMAGAdminAuditCode.STARTING_GOVERNANCE_SERVICES.getMessageDefinition(serverTypeClassifier.getServerType().getServerTypeName(), + serverName)); + + initializeGovernanceServices(instance, + configuration, + serverTypeClassification, + operationalRepositoryServices, + activatedServiceList); + + auditLog.logMessage(actionDescription, + OMAGAdminAuditCode.GOVERNANCE_SERVICES_STARTED.getMessageDefinition(serverTypeClassifier.getServerType().getServerTypeName(), + serverName)); + } + catch (OMAGConfigurationErrorException error) + { + /* + * There is a configuration error that means that the governance services subsystem can not start. Since this is + * the primary function of the server then there is no purpose in continuing. + */ + auditLog.logException(actionDescription, + OMAGAdminAuditCode.GOVERNANCE_SERVICE_FAILURE.getMessageDefinition(error.getClass().getName(), + serverTypeClassifier.getServerType().getServerTypeName(), + serverName, + error.getReportedErrorMessage()), + error); + throw error; + } + catch (Exception error) + { + /* + * Uncontrolled error from the governance service subsystem. The subsystem could be in any state. + * Capture additional information about the error and stop the server startup. + */ + auditLog.logException(actionDescription, + OMAGAdminAuditCode.GOVERNANCE_SERVICE_FAILURE.getMessageDefinition(error.getClass().getName(), + serverTypeClassifier.getServerType().getServerTypeName(), + serverName, + error.getMessage()), + error); + throw error; + } + } + + /* + * All subsystems are started - just log messages and return. + */ + instance.setServerActiveStatus(ServerActiveStatus.RUNNING); + + String successMessage = new Date().toString() + " " + serverName + " is running the following services: " + activatedServiceList.toString(); + + auditLog.logMessage(actionDescription, + OMAGAdminAuditCode.SERVER_STARTUP_SUCCESS.getMessageDefinition(serverName, + activatedServiceList.toString())); + + response.setSuccessMessage(successMessage); + } +// catch (UserNotAuthorizedException error) +// { +// exceptionHandler.captureNotAuthorizedException(response, error); +// cleanUpRunningServiceInstances(userId, serverName, methodName, instance); +// } + catch (OMAGConfigurationErrorException error) + { + exceptionHandler.captureConfigurationErrorException(response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + catch (OMAGInvalidParameterException error) + { + exceptionHandler.captureInvalidParameterException(response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + catch (OMAGNotAuthorizedException error) + { + exceptionHandler.captureNotAuthorizedException(response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + catch (Exception error) + { + exceptionHandler.capturePlatformRuntimeException(serverName, methodName, response, error); + cleanUpRunningServiceInstances(userId, serverName, methodName, instance); + } + + restCallLogger.logRESTCallReturn(token, response.toString()); + return response; + } + /** * There are many paging services in Egeria. This value sets a maximum page size that a requester can use. diff --git a/open-metadata-implementation/server-standalone/pom.xml b/open-metadata-implementation/server-standalone/pom.xml index d2ff5364975..be7bc95e331 100644 --- a/open-metadata-implementation/server-standalone/pom.xml +++ b/open-metadata-implementation/server-standalone/pom.xml @@ -22,12 +22,12 @@ http://github.com/odpi/egeria/tree/main - Standalone Server + Server standalone - A standalone server to host open metadata services. + The server standalone provides an single server to host the open metadata services. - server-standalone + server-chassis pom server-standalone-spring diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle index 8c4eacc4baa..faa1ecda5a5 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle @@ -44,6 +44,7 @@ dependencies { runtimeOnly 'org.hibernate:hibernate-validator' runtimeOnly project(':open-metadata-implementation:platform-services:platform-services-spring') runtimeOnly project(':open-metadata-implementation:admin-services:admin-services-spring') + implementation 'com.fasterxml.jackson.core:jackson-databind' // The following are only included at runtime for the full platform (ie adminChassisOnly is not set as a property) if (!project.hasProperty("adminChassisOnly")) { @@ -106,7 +107,7 @@ dependencies { } } -description = 'OMAG Server Platform Chassis for Spring' +description = 'OMAG Server standalone for Spring' bootJar { manifest { diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml b/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml index 090130c1e15..4bfe58132a0 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/pom.xml @@ -21,7 +21,7 @@ http://github.com/odpi/egeria/tree/main - OMAG Server Platform and stand alone server for Spring + OMAG Server standalone for Spring Provides the spring-based OMAG standalone server. @@ -84,6 +84,22 @@ runtime + + org.odpi.egeria + admin-services-spring + runtime + + + + org.odpi.egeria + admin-services-server + + + + org.odpi.egeria + admin-services-api + + org.odpi.egeria ocf-metadata-spring diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerStandalone.java similarity index 75% rename from open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java rename to open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerStandalone.java index 76dc787237f..12bfbfe5be9 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/StandaloneOMAGServer.java +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/java/org/odpi/openmetadata/serverstandalone/springboot/OMAGServerStandalone.java @@ -2,12 +2,13 @@ /* Copyright Contributors to the ODPi Egeria project. */ package org.odpi.openmetadata.serverstandalone.springboot; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.info.License; -import org.odpi.openmetadata.adminservices.configuration.properties.OMAGServerConfig; import org.odpi.openmetadata.adminservices.server.OMAGServerOperationalServices; import org.odpi.openmetadata.adminservices.rest.SuccessMessageResponse; import org.odpi.openmetadata.http.HttpHelper; @@ -29,6 +30,12 @@ import org.springframework.context.event.EventListener; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; +import org.odpi.openmetadata.adminservices.configuration.properties.OMAGServerConfig; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.*; @@ -60,25 +67,28 @@ "REST APIs may be used for development, testing, evaluation. Click on the documentation for each module to discover more ...", license = @License(name = "Apache 2.0 License", url = "https://www.apache.org/licenses/LICENSE-2.0"), contact = @Contact(url = "https://egeria-project.org", name = "Egeria Project", - email = "egeria-technical-discuss@lists.lfaidata.foundation") + email = "egeria-technical-discuss@lists.lfaidata.foundation") ), externalDocs = @ExternalDocumentation(description = "OMAG Server Platform documentation", url="https://egeria-project.org/concepts/omag-server-platform/") - ) +) @Configuration -public class StandaloneOMAGServer +public class OMAGServerStandalone { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectReader OBJECT_READER = OBJECT_MAPPER.reader(); @Value("${strict.ssl}") Boolean strictSSL; @Value("${startup.user}") String sysUser; - @Value("${startup.server.list}") - String startupServers; + @Value("${server.config.location}") + String configFilelocation; @Value("${header.name.list}") List headerNames; @@ -93,10 +103,10 @@ public class StandaloneOMAGServer private String startupMessage = ""; private OMAGServerOperationalServices operationalServices = new OMAGServerOperationalServices(); - private static final Logger log = LoggerFactory.getLogger(org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class); + private static final Logger log = LoggerFactory.getLogger(OMAGServerStandalone.class); public static void main(String[] args) { - SpringApplication.run(org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.class, args); + SpringApplication.run(OMAGServerStandalone.class, args); } @Bean @@ -116,57 +126,58 @@ public InitializingBean getInitialize() }; } + /** - * Extract the list of servers to auto start along with the administration userId. - * The userId is in property "sysUser" and the list of server names are in property - * "startupServers". If either are null then no servers are auto started. + * Starts the server */ - List getAutoStartList() + private void startServer() { - if (!startupServers.trim().isEmpty()) - { - String[] splits = startupServers.split(","); - //remove eventual duplicates - TreeSet serverSet = new TreeSet(); - Collections.addAll(serverSet, splits); - - if (! serverSet.isEmpty()) - { - return new ArrayList<>(serverSet); + OMAGServerConfig configuration = null; + StartupFailEvent customSpringEvent = null; + try { + System.err.println("configFilelocation="+configFilelocation); + if (configFilelocation != null) { + configuration = OBJECT_READER.readValue(new File(configFilelocation), OMAGServerConfig.class); } + } catch(IOException e) { + startupMessage = "Server startup failed - as configuration could not be read" ; + customSpringEvent = new StartupFailEvent(this, startupMessage); + } + if (configuration !=null) { + SuccessMessageResponse response = operationalServices.activateWithSuppliedConfig(sysUser.trim(), configuration); + + if (response.getRelatedHTTPCode() == 200) { + startupMessage = response.getSuccessMessage(); + } else { + startupMessage = "Server startup failed with error: " + response.getExceptionErrorMessage(); + customSpringEvent = new StartupFailEvent(this, startupMessage); + } + } + if (customSpringEvent !=null) { + applicationEventPublisher.publishEvent(customSpringEvent); + triggeredRuntimeHalt = true; } - return null; } + /** - * Starts the server in the supplied configuration + * Deactivate all servers that were started automatically */ - private void startServer() - { +// private void temporaryDeactivateServers() +// { +// List servers = getAutoStartList(); +// // if (servers != null) // { -// log.info("Startup detected for servers: {}", startupServers); +// log.info("Temporarily deactivating any auto-started servers '{}'", servers); +// +// System.out.println(new Date() + " OMAG Server Platform shutdown requested. Shutting down auto-started servers (if running): " + servers); +// +// operationalServices.deactivateTemporarilyServerList(sysUser, servers); // } - OMAGServerConfig configuration = null; - String userId = "garygeeke"; - SuccessMessageResponse response = operationalServices.activateServerWithSuppliedConfig(userId, configuration); - if (response.getRelatedHTTPCode() == 200) - { - startupMessage = response.getSuccessMessage(); - } - else - { - startupMessage = "Server startup failed with error: " + response.getExceptionErrorMessage(); - - StartupFailEvent customSpringEvent = new StartupFailEvent(this, startupMessage); - applicationEventPublisher.publishEvent(customSpringEvent); - triggeredRuntimeHalt = true; - } - } - - +// } @Component public class ApplicationContextListener @@ -175,7 +186,7 @@ public class ApplicationContextListener @EventListener(ApplicationReadyEvent.class) public void applicationReady() { startServer(); - System.out.println(org.odpi.openmetadata.serverstandalone.springboot.StandaloneOMAGServer.this.startupMessage); + System.out.println(OMAGServerStandalone.this.startupMessage); if(triggeredRuntimeHalt){ Runtime.getRuntime().halt(43); @@ -186,8 +197,7 @@ public void applicationReady() { @EventListener public void onApplicationEvent(ContextClosedEvent event) { -// temporaryDeactivateServers(); - //TODO should we do anything here ? + // temporaryDeactivateServers(); } } @@ -197,8 +207,7 @@ public class CustomSpringEventListener implements ApplicationListener Date: Tue, 14 Mar 2023 11:21:09 +0000 Subject: [PATCH 5/5] git7512 Signed-off-by: David Radley --- .../server-standalone/server-standalone-spring/build.gradle | 4 ++-- .../src/main/resources/application.properties | 2 +- settings.gradle | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle index faa1ecda5a5..f59a447195b 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/build.gradle @@ -42,8 +42,8 @@ dependencies { runtimeOnly 'org.springdoc:springdoc-openapi-ui' implementation 'io.swagger.core.v3:swagger-annotations' runtimeOnly 'org.hibernate:hibernate-validator' - runtimeOnly project(':open-metadata-implementation:platform-services:platform-services-spring') - runtimeOnly project(':open-metadata-implementation:admin-services:admin-services-spring') +// runtimeOnly project(':open-metadata-implementation:platform-services:platform-services-spring') +// runtimeOnly project(':open-metadata-implementation:admin-services:admin-services-spring') implementation 'com.fasterxml.jackson.core:jackson-databind' // The following are only included at runtime for the full platform (ie adminChassisOnly is not set as a property) diff --git a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties index e743df1d7e2..199d74d5649 100644 --- a/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties +++ b/open-metadata-implementation/server-standalone/server-standalone-spring/src/main/resources/application.properties @@ -22,7 +22,7 @@ strict.ssl=true scan.packages=org.odpi.openmetadata.* #userId used to startup the list of configured servers default is 'system' startup.user=system -# server configuration to start with +# Comma separated names of servers to be started server.config.location= # Comma separated values of http headers to be added to ThreadLocal header.name.list= diff --git a/settings.gradle b/settings.gradle index 2311b222a31..552981f79d6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -390,6 +390,7 @@ include(':open-metadata-implementation:server-chassis:server-chassis-spring') include(':open-metadata-implementation:server-chassis') include(':open-metadata-implementation:server-standalone:server-standalone-spring') include(':open-metadata-implementation:server-standalone') +include(':open-metadata-implementation:admin-services:admin-services-standalone-server') include(':open-metadata-implementation:user-interfaces:ui-chassis:ui-chassis-spring') include(':open-metadata-implementation:user-interfaces:ui-chassis') include(':open-metadata-implementation:user-interfaces') @@ -811,6 +812,7 @@ project(':open-metadata-implementation:server-chassis:server-chassis-spring').pr project(':open-metadata-implementation:server-chassis').projectDir = file('open-metadata-implementation/server-chassis') project(':open-metadata-implementation:server-standalone:server-standalone-spring').projectDir = file('open-metadata-implementation/server-standalone/server-standalone-spring') project(':open-metadata-implementation:server-standalone').projectDir = file('open-metadata-implementation/server-standalone') +project(':open-metadata-implementation:admin-services:admin-services-standalone-server').projectDir = file('open-metadata-implementation/admin-services/admin-services-standalone-server') project(':open-metadata-implementation:user-interfaces:ui-chassis:ui-chassis-spring').projectDir = file('open-metadata-implementation/user-interfaces/ui-chassis/ui-chassis-spring') project(':open-metadata-implementation:user-interfaces:ui-chassis').projectDir = file('open-metadata-implementation/user-interfaces/ui-chassis') project(':open-metadata-implementation:user-interfaces').projectDir = file('open-metadata-implementation/user-interfaces')