Fixes #3533 - Discover entity support for tags, owner, and follower using entity fields (#3534)

This commit is contained in:
Suresh Srinivas 2022-03-19 13:49:45 -07:00 committed by GitHub
parent d7e309939e
commit 69adc7ed38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 113 additions and 275 deletions

View File

@ -227,7 +227,9 @@ public class CatalogApplication extends Application<CatalogApplicationConfig> {
private void registerResources(CatalogApplicationConfig config, Environment environment, Jdbi jdbi) {
CollectionRegistry.getInstance().registerResources(jdbi, environment, config, authorizer);
if (config.getElasticSearchConfiguration() != null) {
environment.jersey().register(new SearchResource(config.getElasticSearchConfiguration()));
}
environment.jersey().register(new JsonPatchProvider());
ErrorPageErrorHandler eph = new ErrorPageErrorHandler();
eph.addErrorPage(Response.Status.NOT_FOUND.getStatusCode(), "/");

View File

@ -44,10 +44,7 @@ public class AirflowPipelineRepository extends EntityRepository<AirflowPipeline>
dao.airflowPipelineDAO(),
dao,
AIRFLOW_PIPELINE_PATCH_FIELDS,
AIRFLOW_PIPELINE_UPDATE_FIELDS,
false,
true,
false);
AIRFLOW_PIPELINE_UPDATE_FIELDS);
}
public static String getFQN(AirflowPipeline airflowPipeline) {

View File

@ -33,10 +33,7 @@ public class BotsRepository extends EntityRepository<Bots> {
dao.botsDAO(),
dao,
Fields.EMPTY_FIELDS,
Fields.EMPTY_FIELDS,
false,
false,
false);
Fields.EMPTY_FIELDS);
}
@Override

View File

@ -49,10 +49,7 @@ public class ChartRepository extends EntityRepository<Chart> {
dao.chartDAO(),
dao,
CHART_PATCH_FIELDS,
CHART_UPDATE_FIELDS,
true,
true,
true);
CHART_UPDATE_FIELDS);
}
public static String getFQN(Chart chart) {

View File

@ -53,10 +53,7 @@ public class DashboardRepository extends EntityRepository<Dashboard> {
dao.dashboardDAO(),
dao,
DASHBOARD_PATCH_FIELDS,
DASHBOARD_UPDATE_FIELDS,
true,
true,
true);
DASHBOARD_UPDATE_FIELDS);
}
public static String getFQN(Dashboard dashboard) {

View File

@ -41,10 +41,7 @@ public class DashboardServiceRepository extends EntityRepository<DashboardServic
dao.dashboardServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
UPDATE_FIELDS,
false,
true,
false);
UPDATE_FIELDS);
}
@Override

View File

@ -50,10 +50,7 @@ public class DatabaseRepository extends EntityRepository<Database> {
dao.databaseDAO(),
dao,
DATABASE_PATCH_FIELDS,
DATABASE_UPDATE_FIELDS,
false,
true,
false);
DATABASE_UPDATE_FIELDS);
}
public static String getFQN(Database database) {

View File

@ -50,10 +50,7 @@ public class DatabaseServiceRepository extends EntityRepository<DatabaseService>
dao.dbServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
UPDATE_FIELDS,
false,
true,
false);
UPDATE_FIELDS);
fernet = Fernet.getInstance();
}

View File

@ -15,6 +15,7 @@ package org.openmetadata.catalog.jdbi3;
import static org.openmetadata.catalog.Entity.FIELD_DESCRIPTION;
import static org.openmetadata.catalog.Entity.FIELD_OWNER;
import static org.openmetadata.catalog.Entity.getEntityFields;
import static org.openmetadata.catalog.type.Include.DELETED;
import static org.openmetadata.catalog.util.EntityUtil.compareTagLabel;
import static org.openmetadata.catalog.util.EntityUtil.entityReferenceMatch;
@ -131,10 +132,7 @@ public abstract class EntityRepository<T> {
EntityDAO<T> entityDAO,
CollectionDAO collectionDAO,
Fields patchFields,
Fields putFields,
boolean supportsTags,
boolean supportsOwner,
boolean supportsFollower) {
Fields putFields) {
this.collectionPath = collectionPath;
this.entityClass = entityClass;
this.dao = entityDAO;
@ -142,9 +140,11 @@ public abstract class EntityRepository<T> {
this.patchFields = patchFields;
this.putFields = putFields;
this.entityType = entityType;
this.supportsTags = supportsTags;
this.supportsOwner = supportsOwner;
this.supportsFollower = supportsFollower;
List<String> allowedFields = getEntityFields(entityClass);
this.supportsTags = allowedFields.contains("tags");
this.supportsOwner = allowedFields.contains("owner");
this.supportsFollower = allowedFields.contains("followers");
Entity.registerEntity(entityClass, entityType, dao, this);
}

View File

@ -51,10 +51,7 @@ public class GlossaryRepository extends EntityRepository<Glossary> {
dao.glossaryDAO(),
dao,
PATCH_FIELDS,
UPDATE_FIELDS,
true,
true,
false);
UPDATE_FIELDS);
}
@Transaction

View File

@ -58,10 +58,7 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
dao.glossaryTermDAO(),
dao,
PATCH_FIELDS,
UPDATE_FIELDS,
true,
false,
false);
UPDATE_FIELDS);
}
@Override

View File

@ -54,10 +54,7 @@ public class LocationRepository extends EntityRepository<Location> {
dao.locationDAO(),
dao,
LOCATION_PATCH_FIELDS,
LOCATION_UPDATE_FIELDS,
true,
true,
true);
LOCATION_UPDATE_FIELDS);
}
@Override

View File

@ -42,10 +42,7 @@ public class MessagingServiceRepository extends EntityRepository<MessagingServic
dao.messagingServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
UPDATE_FIELDS,
false,
true,
false);
UPDATE_FIELDS);
}
@Override

View File

@ -44,10 +44,7 @@ public class MetricsRepository extends EntityRepository<Metrics> {
dao.metricsDAO(),
dao,
Fields.EMPTY_FIELDS,
METRICS_UPDATE_FIELDS,
true,
true,
true);
METRICS_UPDATE_FIELDS);
}
public static String getFQN(Metrics metrics) {

View File

@ -56,10 +56,7 @@ public class MlModelRepository extends EntityRepository<MlModel> {
dao.mlModelDAO(),
dao,
MODEL_PATCH_FIELDS,
MODEL_UPDATE_FIELDS,
true,
true,
true);
MODEL_UPDATE_FIELDS);
}
public static String getFQN(MlModel model) {

View File

@ -59,10 +59,7 @@ public class PipelineRepository extends EntityRepository<Pipeline> {
dao.pipelineDAO(),
dao,
PIPELINE_PATCH_FIELDS,
PIPELINE_UPDATE_FIELDS,
true,
true,
true);
PIPELINE_UPDATE_FIELDS);
}
public static String getFQN(Pipeline pipeline) {

View File

@ -39,10 +39,7 @@ public class PipelineServiceRepository extends EntityRepository<PipelineService>
dao.pipelineServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
UPDATE_FIELDS,
false,
true,
false);
UPDATE_FIELDS);
}
@Override

View File

@ -62,10 +62,7 @@ public class PolicyRepository extends EntityRepository<Policy> {
dao.policyDAO(),
dao,
POLICY_PATCH_FIELDS,
POLICY_UPDATE_FIELDS,
false,
true,
false);
POLICY_UPDATE_FIELDS);
policyEvaluator = PolicyEvaluator.getInstance();
}

View File

@ -44,10 +44,7 @@ public class ReportRepository extends EntityRepository<Report> {
dao.reportDAO(),
dao,
Fields.EMPTY_FIELDS,
REPORT_UPDATE_FIELDS,
true,
true,
true);
REPORT_UPDATE_FIELDS);
}
@Override

View File

@ -59,10 +59,7 @@ public class RoleRepository extends EntityRepository<Role> {
dao.roleDAO(),
dao,
ROLE_PATCH_FIELDS,
ROLE_UPDATE_FIELDS,
false,
false,
false);
ROLE_UPDATE_FIELDS);
}
@Override

View File

@ -38,10 +38,7 @@ public class StorageServiceRepository extends EntityRepository<StorageService> {
dao.storageServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
UPDATE_FIELDS,
false,
true,
false);
UPDATE_FIELDS);
}
@Override

View File

@ -93,10 +93,7 @@ public class TableRepository extends EntityRepository<Table> {
dao.tableDAO(),
dao,
TABLE_PATCH_FIELDS,
TABLE_UPDATE_FIELDS,
true,
true,
true);
TABLE_UPDATE_FIELDS);
}
@Override

View File

@ -44,10 +44,7 @@ public class TeamRepository extends EntityRepository<Team> {
dao.teamDAO(),
dao,
TEAM_PATCH_FIELDS,
TEAM_UPDATE_FIELDS,
false,
false,
false);
TEAM_UPDATE_FIELDS);
}
public List<EntityReference> getEntityReferences(List<UUID> ids) {

View File

@ -56,10 +56,7 @@ public class TopicRepository extends EntityRepository<Topic> {
dao.topicDAO(),
dao,
TOPIC_PATCH_FIELDS,
TOPIC_UPDATE_FIELDS,
true,
true,
true);
TOPIC_UPDATE_FIELDS);
}
@Transaction

View File

@ -52,10 +52,7 @@ public class UserRepository extends EntityRepository<User> {
dao.userDAO(),
dao,
USER_PATCH_FIELDS,
USER_UPDATE_FIELDS,
false,
false,
false);
USER_UPDATE_FIELDS);
}
@Override

View File

@ -70,10 +70,7 @@ public class WebhookRepository extends EntityRepository<Webhook> {
dao.webhookDAO(),
dao,
Fields.EMPTY_FIELDS,
Fields.EMPTY_FIELDS,
false,
false,
false);
Fields.EMPTY_FIELDS);
}
@Override

View File

@ -0,0 +1,13 @@
package org.openmetadata.catalog.resources;
import java.util.List;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.jdbi3.EntityRepository;
public class EntityResource<T, K extends EntityRepository<T>> {
protected final List<String> allowedFields;
public EntityResource(Class<T> entityClass, EntityRepository<T> repository) {
allowedFields = Entity.getEntityFields(entityClass);
}
}

View File

@ -24,23 +24,8 @@ public abstract class EntityOperationsResourceTest<T, K> extends EntityResourceT
Class<T> entityClass,
Class<? extends ResultList<T>> entityListClass,
String collectionName,
String fields,
boolean supportsFollowers,
boolean supportsOwner,
boolean supportsTags,
boolean supportsAuthorizedMetadataOperations,
boolean supportsDots) {
super(
entityType,
entityClass,
entityListClass,
collectionName,
fields,
supportsFollowers,
supportsOwner,
supportsTags,
supportsAuthorizedMetadataOperations,
supportsDots);
String fields) {
super(entityType, entityClass, entityListClass, collectionName, fields);
}
// Override the resource path name of regular entities api/v1/<entities> to api/operations/v1/<operations>

View File

@ -160,13 +160,13 @@ public abstract class EntityResourceTest<T, K> extends CatalogApplicationTest {
private final Class<? extends ResultList<T>> entityListClass;
protected final String collectionName;
private final String allFields;
private final boolean supportsFollowers;
private final boolean supportsOwner;
private final boolean supportsTags;
private final boolean supportsDots;
protected final boolean supportsFollowers;
protected boolean supportsOwner;
protected final boolean supportsTags;
protected boolean supportsDots = true;
protected boolean supportsPatch = true;
protected boolean supportsSoftDelete = true;
private final boolean supportsAuthorizedMetadataOperations;
protected boolean supportsAuthorizedMetadataOperations = true;
protected boolean supportsFieldsQueryParam = true;
public static final String DATA_STEWARD_ROLE_NAME = "DataSteward";
@ -234,32 +234,27 @@ public abstract class EntityResourceTest<T, K> extends CatalogApplicationTest {
public static boolean runWebhookTests;
public EntityResourceTest(
String entityTYpe,
String entityType,
Class<T> entityClass,
Class<? extends ResultList<T>> entityListClass,
String collectionName,
String fields,
boolean supportsFollowers,
boolean supportsOwner,
boolean supportsTags,
boolean supportsAuthorizedMetadataOperations,
boolean supportsDots) {
this.entityType = entityTYpe;
String fields) {
this.entityType = entityType;
this.entityClass = entityClass;
this.entityListClass = entityListClass;
this.collectionName = collectionName;
this.allFields = fields;
this.supportsFollowers = supportsFollowers;
this.supportsOwner = supportsOwner;
this.supportsTags = supportsTags;
this.supportsAuthorizedMetadataOperations = supportsAuthorizedMetadataOperations;
this.supportsDots = supportsDots;
ENTITY_RESOURCE_TEST_MAP.put(entityTYpe, this);
List<String> allowedFields = Entity.getEntityFields(entityClass);
this.supportsFollowers = allowedFields.contains("followers");
this.supportsOwner = allowedFields.contains("owner");
this.supportsTags = allowedFields.contains("tags");
ENTITY_RESOURCE_TEST_MAP.put(entityType, this);
}
@BeforeAll
public void setup(TestInfo test) throws URISyntaxException, IOException {
runWebhookTests = new Random().nextBoolean();
if (runWebhookTests) {
webhookCallbackResource.clearEvents();

View File

@ -46,7 +46,7 @@ import org.openmetadata.catalog.util.TestUtils;
public class ChartResourceTest extends EntityResourceTest<Chart, CreateChart> {
public ChartResourceTest() {
super(Entity.CHART, Chart.class, ChartList.class, "charts", ChartResource.FIELDS, true, true, true, true, true);
super(Entity.CHART, Chart.class, ChartList.class, "charts", ChartResource.FIELDS);
}
@BeforeAll

View File

@ -59,17 +59,7 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard, CreateD
public static EntityReference SUPERSET_INVALID_SERVICE_REFERENCE;
public DashboardResourceTest() {
super(
Entity.DASHBOARD,
Dashboard.class,
DashboardList.class,
"dashboards",
DashboardResource.FIELDS,
true,
true,
true,
true,
true);
super(Entity.DASHBOARD, Dashboard.class, DashboardList.class, "dashboards", DashboardResource.FIELDS);
}
@BeforeAll

View File

@ -48,17 +48,7 @@ import org.openmetadata.catalog.util.TestUtils;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DatabaseResourceTest extends EntityResourceTest<Database, CreateDatabase> {
public DatabaseResourceTest() {
super(
Entity.DATABASE,
Database.class,
DatabaseList.class,
"databases",
DatabaseResource.FIELDS,
false,
true,
false,
true,
true);
super(Entity.DATABASE, Database.class, DatabaseList.class, "databases", DatabaseResource.FIELDS);
}
@BeforeAll

View File

@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.Entity.TABLE;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.invalidColumnFQN;
import static org.openmetadata.catalog.type.ColumnDataType.ARRAY;
@ -134,7 +135,7 @@ import org.openmetadata.catalog.util.TestUtils;
public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
public TableResourceTest() {
super(Entity.TABLE, Table.class, TableList.class, "tables", TableResource.FIELDS, true, true, true, true, true);
super(TABLE, Table.class, TableList.class, "tables", TableResource.FIELDS);
}
@BeforeAll

View File

@ -64,7 +64,9 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook, CreateWebho
}
public WebhookResourceTest() {
super(Entity.WEBHOOK, Webhook.class, WebhookList.class, "webhook", "", false, false, false, false, false);
super(Entity.WEBHOOK, Webhook.class, WebhookList.class, "webhook", "");
supportsDots = false;
supportsAuthorizedMetadataOperations = false;
supportsPatch = false;
supportsFieldsQueryParam = false;
}

View File

@ -45,17 +45,8 @@ import org.openmetadata.catalog.util.TestUtils.UpdateType;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GlossaryResourceTest extends EntityResourceTest<Glossary, CreateGlossary> {
public GlossaryResourceTest() {
super(
Entity.GLOSSARY,
Glossary.class,
GlossaryResource.GlossaryList.class,
"glossaries",
GlossaryResource.FIELDS,
false,
true,
true,
true,
false);
super(Entity.GLOSSARY, Glossary.class, GlossaryResource.GlossaryList.class, "glossaries", GlossaryResource.FIELDS);
supportsDots = false;
}
@BeforeAll

View File

@ -68,12 +68,9 @@ public class GlossaryTermResourceTest extends EntityResourceTest<GlossaryTerm, C
GlossaryTerm.class,
GlossaryTermResource.GlossaryTermList.class,
"glossaryTerms",
GlossaryTermResource.FIELDS,
false,
false,
true,
false,
false);
GlossaryTermResource.FIELDS);
supportsDots = false;
supportsAuthorizedMetadataOperations = false; // TODO why?
}
@Order(0)

View File

@ -50,17 +50,7 @@ import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class LocationResourceTest extends EntityResourceTest<Location, CreateLocation> {
public LocationResourceTest() {
super(
Entity.LOCATION,
Location.class,
LocationList.class,
"locations",
LocationResource.FIELDS,
true,
true,
true,
true,
true);
super(Entity.LOCATION, Location.class, LocationList.class, "locations", LocationResource.FIELDS);
}
@BeforeAll

View File

@ -103,17 +103,7 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel, CreateMlMod
new MlHyperParameter().withName("random").withValue("hello"));
public MlModelResourceTest() {
super(
Entity.MLMODEL,
MlModel.class,
MlModelList.class,
"mlmodels",
MlModelResource.FIELDS,
true,
true,
true,
true,
true);
super(Entity.MLMODEL, MlModel.class, MlModelList.class, "mlmodels", MlModelResource.FIELDS);
}
@BeforeAll

View File

@ -94,12 +94,7 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
AirflowPipeline.class,
AirflowPipelineResource.AirflowPipelineList.class,
"airflowPipeline",
AirflowPipelineResource.FIELDS,
false,
true,
false,
true,
true);
AirflowPipelineResource.FIELDS);
}
@BeforeAll

View File

@ -69,17 +69,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline, CreatePip
public static List<Task> TASKS;
public PipelineResourceTest() {
super(
Entity.PIPELINE,
Pipeline.class,
PipelineList.class,
"pipelines",
PipelineResource.FIELDS,
true,
true,
true,
true,
true);
super(Entity.PIPELINE, Pipeline.class, PipelineList.class, "pipelines", PipelineResource.FIELDS);
}
@BeforeAll

View File

@ -67,17 +67,9 @@ public class PolicyResourceTest extends EntityResourceTest<Policy, CreatePolicy>
private static Location location;
public PolicyResourceTest() {
super(
Entity.POLICY,
Policy.class,
PolicyList.class,
"policies",
PolicyResource.FIELDS,
false,
true,
false,
false,
false);
super(Entity.POLICY, Policy.class, PolicyList.class, "policies", PolicyResource.FIELDS);
supportsDots = false;
supportsAuthorizedMetadataOperations = false; // TODO why
}
@BeforeAll

View File

@ -53,13 +53,10 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
DashboardService.class,
DashboardServiceList.class,
"services/dashboardServices",
"owner",
false,
true,
false,
false,
false);
"owner");
this.supportsPatch = false;
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -70,13 +70,10 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
DatabaseService.class,
DatabaseServiceList.class,
"services/databaseServices",
"owner",
false,
true,
false,
false,
false);
"owner");
this.supportsPatch = false;
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -68,13 +68,10 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
MessagingService.class,
MessagingServiceList.class,
"services/messagingServices",
MessagingServiceResource.FIELDS,
false,
true,
false,
false,
false);
MessagingServiceResource.FIELDS);
supportsPatch = false;
supportsDots = false;
supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -64,13 +64,10 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
PipelineService.class,
PipelineServiceList.class,
"services/pipelineServices",
"owner",
false,
true,
false,
false,
false);
"owner");
this.supportsPatch = false;
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@BeforeAll

View File

@ -37,18 +37,10 @@ import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class StorageServiceResourceTest extends EntityResourceTest<StorageService, CreateStorageService> {
public StorageServiceResourceTest() {
super(
Entity.STORAGE_SERVICE,
StorageService.class,
StorageServiceList.class,
"services/storageServices",
"owner",
false,
true,
false,
false,
false);
super(Entity.STORAGE_SERVICE, StorageService.class, StorageServiceList.class, "services/storageServices", "owner");
this.supportsPatch = false;
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -59,7 +59,9 @@ import org.openmetadata.catalog.util.TestUtils;
public class RoleResourceTest extends EntityResourceTest<Role, CreateRole> {
public RoleResourceTest() {
super(Entity.ROLE, Role.class, RoleList.class, "roles", null, false, false, false, false, false);
super(Entity.ROLE, Role.class, RoleList.class, "roles", null);
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -75,7 +75,10 @@ public class TeamResourceTest extends EntityResourceTest<Team, CreateTeam> {
final Profile PROFILE = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
public TeamResourceTest() {
super(Entity.TEAM, Team.class, TeamList.class, "teams", TeamResource.FIELDS, false, false, false, false, false);
super(Entity.TEAM, Team.class, TeamList.class, "teams", TeamResource.FIELDS);
this.supportsOwner = false; // TODO fix the test failures after removing this
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -91,7 +91,9 @@ public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
final Profile PROFILE = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
public UserResourceTest() {
super(Entity.USER, User.class, UserList.class, "users", UserResource.FIELDS, false, false, false, false, false);
super(Entity.USER, User.class, UserList.class, "users", UserResource.FIELDS);
this.supportsDots = false;
this.supportsAuthorizedMetadataOperations = false;
}
@Test

View File

@ -52,7 +52,7 @@ import org.openmetadata.catalog.util.TestUtils.UpdateType;
public class TopicResourceTest extends EntityResourceTest<Topic, CreateTopic> {
public TopicResourceTest() {
super(Entity.TOPIC, Topic.class, TopicList.class, "topics", TopicResource.FIELDS, true, true, true, true, true);
super(Entity.TOPIC, Topic.class, TopicList.class, "topics", TopicResource.FIELDS);
}
@Test

View File

@ -107,9 +107,9 @@ database:
migrationConfiguration:
path: "../bootstrap/sql/mysql"
elasticsearch:
host: localhost
port: 0
#elasticsearch:
# host: localhost
# port: 0
health:
delayedShutdownHandlerEnabled: true