Repository: logging-log4j-audit Updated Branches: refs/heads/master a3f0bc447 -> ace89fa5b
Logging of a dynamic event works Project: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/commit/ace89fa5 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/tree/ace89fa5 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/diff/ace89fa5 Branch: refs/heads/master Commit: ace89fa5b5c21d0facc1b600a8a6c77b8239779e Parents: a3f0bc4 Author: Ralph Goers <rgo...@apache.org> Authored: Fri Dec 29 23:34:47 2017 -0700 Committer: Ralph Goers <rgo...@apache.org> Committed: Fri Dec 29 23:34:47 2017 -0700 ---------------------------------------------------------------------- .../log4j/audit/AbstractEventLogger.java | 6 +- .../log4j/audit/catalog/CatalogManagerImpl.java | 84 +++++++----- .../service/catalog/AuditCatalogManager.java | 15 ++- .../audit/service/catalog/AuditManager.java | 10 ++ .../audit/service/config/WebMvcAppContext.java | 49 +++++-- .../service/controller/CatalogController.java | 6 +- .../src/main/resources/sql/schema.sql | 135 +++++++++++++++++++ 7 files changed, 246 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java index 05fce15..2884eb6 100644 --- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java @@ -129,7 +129,7 @@ public abstract class AbstractEventLogger { } } } - Map<String, Attribute> attributeMap = catalogManager.getAttributes(eventName); + Map<String, Attribute> attributeMap = catalogManager.getAttributes(eventName, event.getCatalogId()); for (String name : attributes.keySet()) { if (!attributeMap.containsKey(name) && !name.equals("completionStatus")) { if (errors.length() > 0) { @@ -147,7 +147,7 @@ public abstract class AbstractEventLogger { if (errors.length() > 0) { throw new AuditException(errors.toString()); } - List<String> attributeNames = catalogManager.getAttributeNames(eventName); + List<String> attributeNames = catalogManager.getAttributeNames(eventName, event.getCatalogId()); StringBuilder buf = new StringBuilder(); for (String attribute : attributes.keySet()) { if (!attributeNames.contains(attribute)) { @@ -161,7 +161,7 @@ public abstract class AbstractEventLogger { throw new AuditException("Event " + eventName + " contains invalid attribute(s) " + buf.toString()); } - List<String> reqCtxAttrs = catalogManager.getRequiredContextAttributes(eventName); + List<String> reqCtxAttrs = catalogManager.getRequiredContextAttributes(eventName, event.getCatalogId()); if (reqCtxAttrs != null) { StringBuilder sb = new StringBuilder(); http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/catalog/CatalogManagerImpl.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/catalog/CatalogManagerImpl.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/catalog/CatalogManagerImpl.java index fd503c7..0e6516d 100644 --- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/catalog/CatalogManagerImpl.java +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/catalog/CatalogManagerImpl.java @@ -52,8 +52,6 @@ public class CatalogManagerImpl implements CatalogManager { private static final String REQCTX = "ReqCtx_"; - - protected CatalogData catalogData; public CatalogManagerImpl(CatalogReader catalogReader) { @@ -64,6 +62,10 @@ public class CatalogManagerImpl implements CatalogManager { } } + protected Map<String, Map<String, CatalogInfo>> getInfoMap() { + return infoMap; + } + @Override public Event getEvent(String eventName, String catalogId) { CatalogInfo info = getCatalogInfo(eventName, catalogId); @@ -79,6 +81,10 @@ public class CatalogManagerImpl implements CatalogManager { @Override public Map<String, Attribute> getAttributes(String eventName, String catalogId) { Event event = getEvent(eventName, catalogId); + if (event == null) { + logger.warn("No event named {} counld be found in catalog {}", eventName, catalogId); + return null; + } Map<String, Attribute> attributes = new HashMap<>(event.getAttributes().size()); for (EventAttribute eventAttribute : event.getAttributes()) { Attribute attr = getAttribute(eventAttribute.getName(), event.getCatalogId()); @@ -140,48 +146,52 @@ public class CatalogManagerImpl implements CatalogManager { Map<String, Map<String, CatalogInfo>> map = new HashMap<>(); map.put(DEFAULT_CATALOG, new HashMap<>()); for (Event event : catalogData.getEvents()) { - CatalogInfo info = new CatalogInfo(); - info.event = event; - String catalogId = event.getCatalogId(); - if (catalogId != null && catalogId.length() > 0 && !map.containsKey(catalogId)) { - map.put(catalogId, new HashMap<>()); - } - List<String> required = new ArrayList<>(); - List<String> names = new ArrayList<>(); - info.attributes = new HashMap<>(names.size()); - if (event.getAttributes() != null) { - for (EventAttribute eventAttribute : event.getAttributes()) { - String name = eventAttribute.getName(); - Attribute attribute = getAttribute(name, event.getCatalogId()); - info.attributes.put(name, attribute); - if (name.indexOf('.') != -1) { - name = name.replaceAll("\\.", ""); - } - if (name.indexOf('/') != -1) { - name = name.replaceAll("/", ""); - } - if (attribute.isRequestContext()) { - if (attribute.isRequired()) { - if (name.startsWith(REQCTX)) { - name = name.substring(REQCTX.length()); - } - required.add(name); + addEntry(map, event); + } + return map; + } + + protected void addEntry(Map<String, Map<String, CatalogInfo>> map, Event event) { + CatalogInfo info = new CatalogInfo(); + info.event = event; + String catalogId = event.getCatalogId(); + if (catalogId != null && catalogId.length() > 0 && !map.containsKey(catalogId)) { + map.put(catalogId, new HashMap<>()); + } + List<String> required = new ArrayList<>(); + List<String> names = new ArrayList<>(); + info.attributes = new HashMap<>(names.size()); + if (event.getAttributes() != null) { + for (EventAttribute eventAttribute : event.getAttributes()) { + String name = eventAttribute.getName(); + Attribute attribute = getAttribute(name, event.getCatalogId()); + info.attributes.put(name, attribute); + if (name.indexOf('.') != -1) { + name = name.replaceAll("\\.", ""); + } + if (name.indexOf('/') != -1) { + name = name.replaceAll("/", ""); + } + if (attribute.isRequestContext()) { + if (attribute.isRequired()) { + if (name.startsWith(REQCTX)) { + name = name.substring(REQCTX.length()); } - } else { - names.add(name); + required.add(name); } + } else { + names.add(name); } } - info.requiredContextAttributes = required; - info.attributeNames = names; - Map<String, CatalogInfo> catalogMap = catalogId == null ? - map.get(DEFAULT_CATALOG) : map.get(catalogId); - catalogMap.put(NamingUtils.getFieldName(event.getName()), info); } - return map; + info.requiredContextAttributes = required; + info.attributeNames = names; + Map<String, CatalogInfo> catalogMap = catalogId == null ? + map.get(DEFAULT_CATALOG) : map.get(catalogId); + catalogMap.put(NamingUtils.getFieldName(event.getName()), info); } - private class CatalogInfo { + protected class CatalogInfo { private Event event; private List<String> requiredContextAttributes; http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditCatalogManager.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditCatalogManager.java b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditCatalogManager.java index 236bd82..74cc35d 100644 --- a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditCatalogManager.java +++ b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditCatalogManager.java @@ -16,7 +16,6 @@ import org.apache.logging.log4j.catalog.api.CatalogReader; import org.apache.logging.log4j.catalog.api.Category; import org.apache.logging.log4j.catalog.api.Event; import org.apache.logging.log4j.catalog.api.Product; -import org.apache.logging.log4j.catalog.api.dao.CatalogDao; import org.apache.logging.log4j.catalog.jpa.model.CatalogModel; import org.apache.logging.log4j.catalog.jpa.service.CatalogService; import org.apache.logging.log4j.catalog.jpa.converter.AttributeConverter; @@ -33,7 +32,7 @@ import org.apache.logging.log4j.catalog.jpa.service.EventService; import org.apache.logging.log4j.catalog.jpa.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; -public class AuditCatalogManager extends CatalogManagerImpl { +public class AuditCatalogManager extends CatalogManagerImpl implements AuditManager { private static Logger logger = LogManager.getLogger(); @@ -53,9 +52,6 @@ public class AuditCatalogManager extends CatalogManagerImpl { ProductService productService; @Autowired - CatalogDao catalogDao; - - @Autowired AttributeConverter attributeConverter; @Autowired @@ -86,6 +82,15 @@ public class AuditCatalogManager extends CatalogManagerImpl { } } + @Override + public EventModel saveEvent(Event event) { + EventModel model = eventConverter.convert(event); + model = eventService.saveEvent(model); + Map<String, Map<String, CatalogInfo>> infoMap = getInfoMap(); + addEntry(infoMap, event); + return model; + } + private void initialize(CatalogModel catalogModel) { logger.debug("Updating static catalog"); http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditManager.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditManager.java b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditManager.java new file mode 100644 index 0000000..476cbfa --- /dev/null +++ b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/catalog/AuditManager.java @@ -0,0 +1,10 @@ +package org.apache.logging.log4j.audit.service.catalog; + +import org.apache.logging.log4j.audit.catalog.CatalogManager; +import org.apache.logging.log4j.catalog.api.Event; +import org.apache.logging.log4j.catalog.jpa.model.EventModel; + +public interface AuditManager extends CatalogManager { + + EventModel saveEvent(Event event); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java index 7300ebd..ce8239a 100644 --- a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java +++ b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java @@ -16,6 +16,7 @@ */ package org.apache.logging.log4j.audit.service.config; +import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -23,11 +24,16 @@ import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.jcraft.jsch.UserInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.audit.AuditLogger; import org.apache.logging.log4j.audit.catalog.CatalogManager; import org.apache.logging.log4j.audit.service.catalog.AuditCatalogManager; +import org.apache.logging.log4j.audit.service.catalog.AuditManager; import org.apache.logging.log4j.audit.service.security.LocalAuthorizationInterceptor; import org.apache.logging.log4j.audit.util.JsonObjectMapperFactory; import org.apache.logging.log4j.catalog.api.dao.CatalogDao; @@ -35,8 +41,15 @@ import org.apache.logging.log4j.catalog.api.CatalogReader; import org.apache.logging.log4j.catalog.api.dao.ClassPathCatalogReader; import org.apache.logging.log4j.catalog.api.util.CatalogEventFilter; import org.apache.logging.log4j.catalog.git.dao.GitCatalogDao; +import org.eclipse.jgit.api.TransportConfigCallback; import org.eclipse.jgit.transport.CredentialsProvider; +import org.eclipse.jgit.transport.JschConfigSessionFactory; +import org.eclipse.jgit.transport.OpenSshConfig; +import org.eclipse.jgit.transport.SshSessionFactory; +import org.eclipse.jgit.transport.SshTransport; +import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.util.FS; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -57,6 +70,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; +import static org.apache.commons.lang3.StringUtils.isNotBlank; @Configuration @@ -71,6 +85,27 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter { @Autowired ConfigurationService configurationService; + @Value("${gitUserName") + private String gitUserName; + + @Value("${gitPassword:#{null}}") + private String gitPassword; + + @Value("${gitPassPhrase:#{null}}") + private String gitPassPhrase; + + @Value("${gitLocalRepoPath:#{null}}") + private String localRepoUrl; + + @Value("${privateKeyPath:#{null}}") + private String privateKeyPath; + + @Value("${getRemoteRepoUri}") + private String remoteRepoUrl; + + @Value("${remoteRepoCatalogPath:#{null}}") + private String remoteRepoCatalogPath; + @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); @@ -148,16 +183,6 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter { } @Bean - public CatalogDao catalogDao(@Value("${gitLocalRepoPath}") String gitLocalRepoPath, @Value("${gitRemoteRepoUri}") String gitRemoteRepoUri) { - GitCatalogDao catalogDao = new GitCatalogDao(); - catalogDao.setLocalRepoPath(gitLocalRepoPath); - catalogDao.setRemoteRepoUri(gitRemoteRepoUri); - CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider("waymirec", "w4ym1r3c"); - catalogDao.setCredentialsProvider(credentialsProvider); - return catalogDao; - } - - @Bean public CatalogReader catalogReader() { try { return new ClassPathCatalogReader(); @@ -168,14 +193,14 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter { } @Bean - public CatalogManager catalogManager() { + public AuditManager auditManager() { return new AuditCatalogManager(catalogReader()); } @Bean AuditLogger auditLogger() { AuditLogger auditLogger = new AuditLogger(); - auditLogger.setCatalogManager(catalogManager()); + auditLogger.setCatalogManager(auditManager()); return auditLogger; } http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/CatalogController.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/CatalogController.java b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/CatalogController.java index 3ccfaae..21fe1ab 100644 --- a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/CatalogController.java +++ b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/CatalogController.java @@ -12,6 +12,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.audit.service.catalog.AuditManager; import org.apache.logging.log4j.catalog.api.Attribute; import org.apache.logging.log4j.catalog.api.Category; import org.apache.logging.log4j.catalog.api.Event; @@ -90,6 +91,8 @@ public class CatalogController { @Autowired private CategoryService categoryService; + @Autowired + private AuditManager auditManager; @Autowired private CategoryModelConverter categoryModelConverter; @@ -243,8 +246,7 @@ public class CatalogController { throw new IllegalStateException("An event named "+ event.getName() + " in catalog " + event.getCatalogId() + " already exists"); } - EventModel model = eventConverter.convert(event); - model = eventService.saveEvent(model); + EventModel model = auditManager.saveEvent(event); return new ResponseEntity<>(eventModelConverter.convert(model), HttpStatus.CREATED); } http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/ace89fa5/log4j-audit/log4j-audit-war/src/main/resources/sql/schema.sql ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-war/src/main/resources/sql/schema.sql b/log4j-audit/log4j-audit-war/src/main/resources/sql/schema.sql new file mode 100644 index 0000000..78e5475 --- /dev/null +++ b/log4j-audit/log4j-audit-war/src/main/resources/sql/schema.sql @@ -0,0 +1,135 @@ +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +CREATE TABLE CATALOG +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + LAST_UPDATE TIMESTAMP NOT NULL +); + +CREATE TABLE EVENT_ATTRIBUTE +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + CATALOG_ID VARCHAR(64) NOT NULL, + NAME VARCHAR(64) NOT NULL, + DISPLAY_NAME VARCHAR(64) NOT NULL, + DESCRIPTION VARCHAR(1024), + DATATYPE VARCHAR(64), + INDEXED CHAR, + SORTABLE CHAR, + REQUIRED CHAR, + REQUEST_CONTEXT CHAR +); + +CREATE INDEX ATTRIBUTE_NAME ON EVENT_ATTRIBUTE(NAME); + +CREATE UNIQUE INDEX IDX_ATTR_CATID_NAME ON EVENT_ATTRIBUTE(CATALOG_ID, NAME); + +CREATE TABLE ATTRIBUTE_EXAMPLES +( + ATTRIBUTE_ID BIGINT NOT NULL, + EXAMPLE VARCHAR(64), + FOREIGN KEY (ATTRIBUTE_ID) REFERENCES EVENT_ATTRIBUTE(ID), +); + +CREATE TABLE ATTRIBUTE_ALIASES +( + ATTRIBUTE_ID BIGINT NOT NULL, + ALIAS VARCHAR(64), + FOREIGN KEY (ATTRIBUTE_ID) REFERENCES EVENT_ATTRIBUTE(ID), +); + +CREATE TABLE ATTRIBUTE_CONSTRAINT +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + ATTRIBUTE_ID BIGINT NOT NULL, + CONSTRAINT_TYPE VARCHAR(32) NOT NULL, + VALUE VARCHAR(256), + FOREIGN KEY (ATTRIBUTE_ID) REFERENCES EVENT_ATTRIBUTE(ID), +); + +CREATE TABLE CATALOG_EVENT +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + CATALOG_ID VARCHAR(64) NOT NULL, + NAME VARCHAR(64) NOT NULL, + DISPLAY_NAME VARCHAR(64) NOT NULL, + DESCRIPTION VARCHAR(1024) +); + +CREATE INDEX EVENT_NAME ON CATALOG_EVENT(NAME); + +CREATE UNIQUE INDEX IDX_EVENT_CATID_NAME ON CATALOG_EVENT(CATALOG_ID, NAME); + +CREATE TABLE EVENT_ALIASES +( + EVENT_ID BIGINT NOT NULL, + ALIAS VARCHAR(64) NOT NULL, + FOREIGN KEY (EVENT_ID) REFERENCES CATALOG_EVENT(ID), +); + +CREATE TABLE EVENT_ATTRIBUTES +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + EVENT_ID BIGINT NOT NULL, + ATTRIBUTE_ID BIGINT NOT NULL, + IS_REQUIRED CHAR NOT NULL, + FOREIGN KEY (EVENT_ID) REFERENCES CATALOG_EVENT(ID), + FOREIGN KEY (ATTRIBUTE_ID) REFERENCES EVENT_ATTRIBUTE(ID) +); + +CREATE TABLE CATALOG_CATEGORY +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + CATALOG_ID VARCHAR(64) NOT NULL, + NAME VARCHAR(64) NOT NULL, + DISPLAY_NAME VARCHAR(64) NOT NULL, + DESCRIPTION VARCHAR(1024) + +); + +CREATE INDEX CATEGORY_NAME ON CATALOG_CATEGORY(NAME); + +CREATE UNIQUE INDEX IDX_CATEGORY_CATID_NAME ON CATALOG_CATEGORY(CATALOG_ID, NAME); + +CREATE TABLE CATEGORY_EVENTS +( + CATEGORY_ID BIGINT NOT NULL, + EVENT_ID BIGINT NOT NULL, + FOREIGN KEY (CATEGORY_ID) REFERENCES CATALOG_CATEGORY(ID), + FOREIGN KEY (EVENT_ID) REFERENCES CATALOG_EVENT(ID) +); + +CREATE TABLE CATALOG_PRODUCT +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, + CATALOG_ID VARCHAR(64) NOT NULL, + NAME VARCHAR(64) NOT NULL, + DISPLAY_NAME VARCHAR(64) NOT NULL, + DESCRIPTION VARCHAR(1024) + +); + +CREATE INDEX PRODUCT_NAME ON CATALOG_PRODUCT(NAME); + +CREATE UNIQUE INDEX IDX_PRODUCT_CATID_NAME ON CATALOG_PRODUCT(CATALOG_ID, NAME); + +CREATE TABLE PRODUCT_EVENTS +( + PRODUCT_ID BIGINT NOT NULL, + EVENT_ID BIGINT NOT NULL, + FOREIGN KEY (PRODUCT_ID) REFERENCES CATALOG_PRODUCT(ID), + FOREIGN KEY (EVENT_ID) REFERENCES CATALOG_EVENT(ID) +); \ No newline at end of file