You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2017/09/03 02:18:37 UTC
[26/33] logging-log4j-audit git commit: Initial commit
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ConstraintServiceImpl.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ConstraintServiceImpl.java b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ConstraintServiceImpl.java
new file mode 100644
index 0000000..8583175
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ConstraintServiceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.jpa.service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.api.plugins.ConstraintPlugins;
+import org.apache.logging.log4j.catalog.jpa.dao.ConstraintRepository;
+import org.apache.logging.log4j.catalog.jpa.model.ConstraintModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Repository
+@Transactional
+public class ConstraintServiceImpl implements ConstraintService {
+ private static final Logger LOGGER = LogManager.getLogger();
+
+ @Autowired
+ private ConstraintRepository constraintRepository;
+
+ @Override
+ public Set<String> getConstraintTypes() {
+ return ConstraintPlugins.getInstance().getConstraintMap().keySet();
+ }
+
+ @Override
+ public List<ConstraintModel> getConstraints() {
+ return constraintRepository.findAll();
+ }
+
+ @Override
+ public Optional<ConstraintModel> getConstraint(Long constraintId) {
+ return constraintRepository.findOne(constraintId);
+ }
+
+ @Override
+ public ConstraintModel saveConstraint(ConstraintModel constraint) {
+ return constraintRepository.save(constraint);
+ }
+
+ @Override
+ public void deleteConstraint(Long constraintId) {
+ constraintRepository.deleteById(constraintId);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventService.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventService.java b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventService.java
new file mode 100644
index 0000000..5382545
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventService.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.jpa.service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.logging.log4j.catalog.jpa.model.EventModel;
+
+/**
+ *
+ */
+public interface EventService {
+ List<EventModel> getEvents(int startPage, int itemsPerPage, String sortColumn, String direction);
+ List<EventModel> getEvents();
+ Map<String, EventModel> getEventMap();
+ Optional<EventModel> getEvent(Long eventId);
+ EventModel saveEvent(EventModel event);
+ void deleteEvent(Long eventId);
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventServiceImpl.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventServiceImpl.java b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventServiceImpl.java
new file mode 100644
index 0000000..f7852b5
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/EventServiceImpl.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.jpa.service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.jpa.dao.EventRepository;
+import org.apache.logging.log4j.catalog.jpa.model.EventModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Repository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Repository
+@Transactional
+public class EventServiceImpl extends AbstractPagingAndSortingService implements EventService {
+ private static final Logger LOGGER = LogManager.getLogger();
+
+ @Autowired
+ private EventRepository eventRepository;
+
+ @Override
+ public List<EventModel> getEvents() {
+ return eventRepository.findAll();
+ }
+
+ @Override
+ public List<EventModel> getEvents(int startPage, int itemsPerPage, String sortColumn, String direction) {
+ Pageable pageable = createPageRequest(startPage, itemsPerPage, sortColumn, direction);
+ Page<EventModel> page = eventRepository.findAll(pageable);
+ return page.getContent();
+ }
+
+ @Override
+ public Map<String, EventModel> getEventMap() {
+ List<EventModel> events = getEvents();
+ Map<String, EventModel> eventMap = new HashMap<>(events.size());
+ for (EventModel event : events) {
+ eventMap.put(event.getName(), event);
+ }
+ return eventMap;
+ }
+
+ @Override
+ public Optional<EventModel> getEvent(Long eventId) {
+ return eventRepository.findOne(eventId);
+ }
+
+ @Override
+ public EventModel saveEvent(EventModel event) {
+ return eventRepository.save(event);
+ }
+
+ @Override
+ public void deleteEvent(Long eventId) {
+ eventRepository.deleteById(eventId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductService.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductService.java b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductService.java
new file mode 100644
index 0000000..4263090
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductService.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.jpa.service;
+
+import org.apache.logging.log4j.catalog.jpa.model.ProductModel;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface ProductService {
+ List<ProductModel> getProducts(int startPage, int itemsPerPage, String sortColumn, String direction);
+ List<ProductModel> getProducts();
+ Optional<ProductModel> getProduct(Long productId);
+ ProductModel saveProduct(ProductModel product);
+ void deleteProduct(Long productId);
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductServiceImpl.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductServiceImpl.java b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductServiceImpl.java
new file mode 100644
index 0000000..92ed9a4
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/main/java/org/apache/logging/log4j/catalog/jpa/service/ProductServiceImpl.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.jpa.service;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.jpa.dao.ProductRepository;
+import org.apache.logging.log4j.catalog.jpa.model.ProductModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Repository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Repository
+@Transactional
+public class ProductServiceImpl extends AbstractPagingAndSortingService implements ProductService {
+ private static final Logger LOGGER = LogManager.getLogger();
+
+ @Autowired
+ private ProductRepository productRepository;
+
+ @Override
+ public List<ProductModel> getProducts() {
+ return productRepository.findAll();
+ }
+
+ @Override
+ public List<ProductModel> getProducts(int startPage, int itemsPerPage, String sortColumn, String direction) {
+ Pageable pageable = createPageRequest(startPage, itemsPerPage, sortColumn, direction);
+ Page<ProductModel> page = productRepository.findAll(pageable);
+ return page.getContent();
+ }
+
+ @Override
+ public Optional<ProductModel> getProduct(Long productId) {
+ return productRepository.findOne(productId);
+ }
+
+ @Override
+ public ProductModel saveProduct(ProductModel product) {
+ return productRepository.save(product);
+ }
+
+ @Override
+ public void deleteProduct(Long productId) {
+ productRepository.deleteById(productId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/main/resources/sql/schema.sql
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/main/resources/sql/schema.sql b/log4j-catalog/log4j-catalog-jpa/src/main/resources/sql/schema.sql
new file mode 100644
index 0000000..1618e73
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/main/resources/sql/schema.sql
@@ -0,0 +1,121 @@
+/*
+ * 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 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 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 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 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 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
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/test/java/org/apache/logging/log4j/catalog/jpa/CatalogTest.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/test/java/org/apache/logging/log4j/catalog/jpa/CatalogTest.java b/log4j-catalog/log4j-catalog-jpa/src/test/java/org/apache/logging/log4j/catalog/jpa/CatalogTest.java
new file mode 100644
index 0000000..8e2a7a5
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/test/java/org/apache/logging/log4j/catalog/jpa/CatalogTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+package org.apache.logging.log4j.catalog.jpa;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.logging.log4j.catalog.api.CatalogData;
+import org.apache.logging.log4j.catalog.api.DataType;
+import org.apache.logging.log4j.catalog.api.service.CatalogService;
+import org.apache.logging.log4j.catalog.jpa.config.ApplicationConfiguration;
+import org.apache.logging.log4j.catalog.jpa.dao.AttributeRepository;
+import org.apache.logging.log4j.catalog.jpa.dao.CategoryRepository;
+import org.apache.logging.log4j.catalog.jpa.dao.EventRepository;
+import org.apache.logging.log4j.catalog.jpa.model.AttributeModel;
+import org.apache.logging.log4j.catalog.jpa.model.EventAttributeModel;
+import org.apache.logging.log4j.catalog.jpa.model.EventModel;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.jdbc.Sql;
+import org.springframework.test.context.jdbc.SqlGroup;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import static org.junit.Assert.*;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = {ApplicationConfiguration.class})
+@SqlGroup({
+ @Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/beforeTestRun.sql"),
+ @Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:sql/afterTestRun.sql")
+})
+@Repository
+public class CatalogTest {
+
+ @Autowired
+ AttributeRepository attributeRepository;
+ @Autowired
+ CategoryRepository categoryRepository;
+ @Autowired
+ EventRepository eventRepository;
+ @Autowired
+ private CatalogService catalogService;
+
+ @BeforeClass
+ public static void initTest() {
+ try {
+ System.setProperty("environment", "lab");
+ System.setProperty("site", "dev1");
+ System.setProperty("applicationName", "CatalogService");
+ } catch (RuntimeException ex) {
+ throw ex;
+ }
+ }
+
+ @Test
+ public void testRetrieveEvents() {
+ List<EventModel> events = eventRepository.findAll();
+ assertNotNull(events);
+ assertFalse(events.isEmpty());
+ assertEquals(4, events.size());
+ }
+
+ @Test
+ public void testRetrieveEvent() {
+ Optional<EventModel> optEvent = eventRepository.findOne(1L);
+ assertTrue(optEvent.isPresent());
+ EventModel event = optEvent.get();
+ assertNotNull(event);
+ assertEquals("login", event.getName());
+ }
+
+ @Test
+ public void testAddAndUpdateEvent() {
+ EventModel event = new EventModel();
+ event.setName("test" + System.nanoTime());
+ event.setDisplayName("Test -- " + System.nanoTime());
+ event.setDescription("foo");
+
+ AttributeModel attr = new AttributeModel();
+ attr.setName("Attr1 -- " + System.nanoTime());
+ attr.setDisplayName("Attribute #1 -- " + System.nanoTime());
+ attr.setDescription("Test Attribute");
+ attr.setDataType(DataType.BOOLEAN);
+ attr.setIndexed(true);
+ attr.setRequestContext(true);
+ attr.setRequired(true);
+ attr.setSortable(true);
+ attr = attributeRepository.save(attr);
+ AttributeModel attr2 = new AttributeModel();
+ attr2.setName("Attr2 -- " + System.nanoTime());
+ attr2.setDisplayName("Attribute #2 -- " + System.nanoTime());
+ attr2.setDescription("Test Attribute Number 2");
+ attr2.setDataType(DataType.BOOLEAN);
+ attr2.setIndexed(false);
+ attr2.setRequestContext(false);
+ attr2.setRequired(false);
+ attr2.setSortable(false);
+ attr2 = attributeRepository.save(attr2);
+ EventAttributeModel eventAttribute = new EventAttributeModel();
+ eventAttribute.setAttribute(attr);
+ eventAttribute.setEvent(event);
+ eventAttribute.setRequired(true);
+ event.addEventAttribute(eventAttribute);
+ EventModel persisted = null;
+ try {
+ persisted = eventRepository.save(event);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ fail();
+ }
+ assertNotNull(persisted);
+ assertNotNull(persisted.getId());
+ assertTrue(event.equals(persisted));
+ assertNotNull(persisted.getAttributes());
+ assertFalse(persisted.getAttributes().isEmpty());
+ assertEquals(event.getAttributes().size(), persisted.getAttributes().size());
+ eventAttribute = new EventAttributeModel();
+ eventAttribute.setAttribute(attr2);
+ eventAttribute.setEvent(persisted);
+ eventAttribute.setRequired(false);
+ persisted.addEventAttribute(eventAttribute);
+ Long id = persisted.getId();
+ try {
+ persisted = eventRepository.save(event);
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ fail();
+ }
+ assertNotNull(persisted);
+ assertNotNull(persisted.getId());
+ assertTrue(persisted.getId().equals(id));
+ assertNotNull(persisted.getAttributes());
+ assertFalse(persisted.getAttributes().isEmpty());
+ assertEquals(event.getAttributes().size(), persisted.getAttributes().size());
+ }
+
+ @Test
+ public void testModifyEvent() {
+
+ }
+
+ @Test
+ public void testDeleteEvent() {
+
+ }
+
+ @Test
+ public void testRetrieveAttributes() {
+ List<AttributeModel> attributes = attributeRepository.findAll();
+ assertNotNull(attributes);
+ assertFalse(attributes.isEmpty());
+ assertEquals(10, attributes.size());
+ }
+
+ @Test
+ public void testRetrieveAttribute() {
+ Optional<AttributeModel> optAttr = attributeRepository.findOne(1L);
+ assertTrue(optAttr.isPresent());
+ AttributeModel attr = optAttr.get();
+ assertNotNull(attr);
+ assertEquals("accountNumber", attr.getName());
+ }
+
+ @Test
+ public void testAddAttribute() {
+
+ }
+
+ @Test
+ public void testModifyAttribute() {
+ }
+
+ @Test
+ public void testDeleteAttribute() {
+ }
+
+ @Test
+ public void testRetrieveCatalog() {
+ CatalogData data = catalogService.getCatalogData();
+ assertNotNull("No catalog data was returned", data);
+ assertEquals("Incorrect number of products", 1, data.getProducts().size());
+ assertEquals("Incorrect number of events", 4, data.getEvents().size());
+ assertEquals("Incorrect number of attributes", 10, data.getAttributes().size());
+ assertEquals("Incorrect number of categories", 2, data.getCategories().size());
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/test/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/test/resources/log4j2.xml b/log4j-catalog/log4j-catalog-jpa/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..1c4bcca
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/test/resources/log4j2.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache license, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the license for the specific language governing permissions and
+ ~ limitations under the license.
+ -->
+<Configuration status="ERROR">
+ <properties>
+ <property name="LOG_DIR">target/logs</property>
+ </properties>
+ <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d{ABSOLUTE} %-5level # %class.%method %m%n" />
+ </Console>
+
+ <RollingFile name="log4j" fileName="${LOG_DIR}/log4j.txt" filePattern="${LOG_DIR}/archive/log4j.txt.%d{yyyyMMdd_HH}-%i">
+ <PatternLayout>
+ <MarkerPatternSelector defaultPattern="%d [%t] %-5p %C{1.}.%M:%L - %m%n">
+ <PatternMatch key="FLOW" pattern="%d [%t] %-5p -------- %C{1.}.%M:%L %msg --------%n"/>
+ </MarkerPatternSelector>
+ </PatternLayout>
+ <Policies>
+ <SizeBasedTriggeringPolicy size="30 MB"/>
+ </Policies>
+ <DefaultRolloverStrategy min="1" max="20"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="debug">
+ <AppenderRef ref="log4j" />
+ </Root>
+ </Loggers>
+</Configuration>
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/afterTestRun.sql
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/afterTestRun.sql b/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/afterTestRun.sql
new file mode 100644
index 0000000..b9fe1d2
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/afterTestRun.sql
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+DELETE FROM PRODUCT_EVENTS;
+DELETE FROM CATEGORY_EVENTS;
+DELETE FROM EVENT_ATTRIBUTES;
+DELETE FROM CATALOG_PRODUCT;
+DELETE FROM CATALOG_CATEGORY;
+DELETE FROM CATALOG_EVENT;
+DELETE FROM ATTRIBUTE_CONSTRAINT;
+DELETE FROM ATTRIBUTE_EXAMPLES;
+DELETE FROM EVENT_ATTRIBUTE;
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/beforeTestRun.sql
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/beforeTestRun.sql b/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/beforeTestRun.sql
new file mode 100644
index 0000000..95be80a
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-jpa/src/test/resources/sql/beforeTestRun.sql
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+INSERT INTO CATALOG_PRODUCT VALUES (1, 'DEFAULT', 'banking', 'Banking', 'Fictional banking product');
+
+INSERT INTO EVENT_ATTRIBUTE VALUES (1, 'DEFAULT', 'accountNumber', 'Account Number', 'Company account number', 'int', 'Y', 'Y', 'Y', 'Y');
+INSERT INTO EVENT_ATTRIBUTE VALUES (2, 'DEFAULT', 'ipAddress', 'IP Address', 'IP address of the caller', 'string', 'Y', 'Y', 'N', 'Y');
+INSERT INTO EVENT_ATTRIBUTE VALUES (3, 'DEFAULT', 'userId', 'UserId', 'Id of the user', 'int', 'Y', 'Y', 'Y', 'Y');
+INSERT INTO EVENT_ATTRIBUTE VALUES (4, 'DEFAULT', 'loginId', 'LoginId', 'Id user logs in with', 'string', 'Y', 'Y', 'Y', 'Y');
+INSERT INTO EVENT_ATTRIBUTE VALUES (5, 'DEFAULT', 'hostName', 'Host Name', 'Name of the server', 'string', 'Y', 'Y', 'N', 'Y');
+INSERT INTO EVENT_ATTRIBUTE VALUES (6, 'DEFAULT', 'fromAccount', 'From Account Number', 'Source of funds', 'int', 'N', 'N', 'Y', 'N');
+INSERT INTO EVENT_ATTRIBUTE VALUES (7, 'DEFAULT', 'toAccount', 'To Account Number', 'Destination account', 'int', 'N', 'N', 'Y', 'N');
+INSERT INTO EVENT_ATTRIBUTE VALUES (8, 'DEFAULT', 'amount', 'Amount', 'Amount to transfer', 'bigDecimal', 'N', 'N', 'Y', 'N');
+INSERT INTO EVENT_ATTRIBUTE VALUES (9, 'DEFAULT', 'account', 'Account Number', 'Account number', 'int', 'N', 'N', 'Y', 'N');
+INSERT INTO EVENT_ATTRIBUTE VALUES (10, 'DEFAULT', 'payee', 'Payee', 'Recipient of payment', 'string', 'N', 'N', 'Y', 'N');
+
+INSERT INTO ATTRIBUTE_EXAMPLES VALUES (2, '127.0.0.1')
+
+INSERT INTO CATALOG_EVENT VALUES (1, 'DEFAULT', 'login', 'Login', 'User login');
+INSERT INTO CATALOG_EVENT VALUES (2, 'DEFAULT', 'transfer', 'Transfer', 'Transfer between accounts');
+INSERT INTO CATALOG_EVENT VALUES (3, 'DEFAULT', 'deposit', 'Deposit', 'Deposit funds');
+INSERT INTO CATALOG_EVENT VALUES (4, 'DEFAULT', 'billPay', 'Bill Pay', 'Payment of a bill');
+
+INSERT INTO EVENT_ATTRIBUTES VALUES (1, 2, 6, 'Y');
+INSERT INTO EVENT_ATTRIBUTES VALUES (2, 2, 7, 'Y');
+INSERT INTO EVENT_ATTRIBUTES VALUES (3, 2, 8, 'Y');
+INSERT INTO EVENT_ATTRIBUTES VALUES (4, 3, 8, 'Y');
+INSERT INTO EVENT_ATTRIBUTES VALUES (5, 3, 9, 'Y');
+INSERT INTO EVENT_ATTRIBUTES VALUES (6, 4, 10, 'Y');
+INSERT INTO EVENT_ATTRIBUTES VALUES (7, 4, 8, 'Y');
+
+INSERT INTO ATTRIBUTE_CONSTRAINT VALUES (1, 2, 'pattern', '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$');
+
+INSERT INTO PRODUCT_EVENTS VALUES (1, 1);
+INSERT INTO PRODUCT_EVENTS VALUES (1, 2);
+INSERT INTO PRODUCT_EVENTS VALUES (1, 3);
+
+INSERT INTO CATALOG_CATEGORY VALUES (1, 'DEFAULT', 'account', 'Account', 'Events related to accounts');
+INSERT INTO CATALOG_CATEGORY VALUES (2, 'DEFAULT', 'billPay', 'Bill Pay', 'Events related to bill payment');
+
+INSERT INTO CATEGORY_EVENTS VALUES (1, 1);
+INSERT INTO CATEGORY_EVENTS VALUES (1, 2);
+INSERT INTO CATEGORY_EVENTS VALUES (1, 3);
+INSERT INTO CATEGORY_EVENTS VALUES (2, 4);
+
+
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-war/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-war/pom.xml b/log4j-catalog/log4j-catalog-war/pom.xml
new file mode 100644
index 0000000..152421c
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-war/pom.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-catalog</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>log4j-catalog-war</artifactId>
+ <packaging>war</packaging>
+
+ <name>Log4j Catalog Service</name>
+ <url>http://maven.apache.org</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>jstl</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-catalog-git</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-catalog-jpa</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-catalog-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-rest-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jsr310</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-jpa</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.modelmapper</groupId>
+ <artifactId>modelmapper</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.modelmapper.extensions</groupId>
+ <artifactId>modelmapper-spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.modelmapper.extensions</groupId>
+ <artifactId>modelmapper-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.thymeleaf</groupId>
+ <artifactId>thymeleaf</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.thymeleaf</groupId>
+ <artifactId>thymeleaf-spring4</artifactId>
+
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>AuditCatalog</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ <executions>
+ <execution>
+ <id>default-war</id>
+ <goals>
+ <goal>war</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/JsonObjectMapperFactory.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/JsonObjectMapperFactory.java b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/JsonObjectMapperFactory.java
new file mode 100644
index 0000000..fdd0cb9
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/JsonObjectMapperFactory.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016 Nextiva, Inc. to Present.
+ * All rights reserved.
+ */
+package org.apache.logging.log4j.catalog.config;
+
+import java.io.IOException;
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+
+/**
+ * Extends Jackson ObjectMapper to support Java LocalDateTime.
+ */
+public final class JsonObjectMapperFactory {
+ /**
+ * Date/Time format.
+ */
+ private static final String LOCAL_DATE_TIME_FORMAT = "yyyyMMddHHmmss.SSS";
+
+ /**
+ * LocalDateTime formatter that converts to and from a format usable in REST requests.
+ */
+ private static final DateTimeFormatter LOCAL_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(LOCAL_DATE_TIME_FORMAT);
+
+ /**
+ * Date/Time format.
+ */
+ private static final String LOCAL_DATE_FORMAT = "yyyyMMdd";
+
+ /**
+ * LocalDateTime formatter that converts to and from a format usable in REST requests.
+ */
+ private static final DateTimeFormatter LOCAL_DATE_FORMATTER = DateTimeFormatter.ofPattern(LOCAL_DATE_FORMAT);
+
+ /**
+ * Date/Time format.
+ */
+ private static final String ZONED_DATE_TIME_FORMAT = "yyyyMMddHHmmss.SSSZ";
+
+ /**
+ * LocalDateTime formatter that converts to and from a format usable in REST requests.
+ */
+ public static final DateTimeFormatter ZONED_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(ZONED_DATE_TIME_FORMAT);
+
+ private JsonObjectMapperFactory() {
+ }
+
+ /**
+ * Create an ObjectMapper using the standard LocalDateTime format.
+ * @return The ObjectMapper.
+ */
+ public static ObjectMapper createMapper() {
+ ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build();
+ DateTimeFormatter dateTimeFormatter = LOCAL_DATE_TIME_FORMATTER;
+ DateTimeFormatter dateFormatter = LOCAL_DATE_FORMATTER;
+ DateTimeFormatter zonedTimeFormatter = ZONED_DATE_TIME_FORMATTER;
+ SimpleModule module = new SimpleModule();
+ module.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
+ @Override
+ public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator,
+ SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+ jsonGenerator.writeString(dateTimeFormatter.format(localDateTime));
+ }
+ });
+ module.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
+ @Override
+ public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
+ String string = parser.getText().trim();
+ if (string.length() == 0) {
+ return null;
+ }
+ try {
+ return LocalDateTime.parse(string, dateTimeFormatter);
+ } catch (DateTimeException e) {
+ throw JsonMappingException.from(parser,
+ String.format("Failed to deserialize %s: (%s) %s",
+ handledType().getName(), e.getClass().getName(), e.getMessage()), e);
+ }
+ }
+ });
+ module.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
+ @Override
+ public void serialize(ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator,
+ SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+ jsonGenerator.writeString(zonedTimeFormatter.format(zonedDateTime));
+ }
+ });
+ module.addDeserializer(ZonedDateTime.class, new JsonDeserializer<ZonedDateTime>() {
+ @Override
+ public ZonedDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
+ String string = parser.getText().trim();
+ if (string.length() == 0) {
+ return null;
+ }
+ try {
+ return ZonedDateTime.parse(string, zonedTimeFormatter);
+ } catch (DateTimeException e) {
+ throw JsonMappingException.from(parser,
+ String.format("Failed to deserialize %s: (%s) %s",
+ handledType().getName(), e.getClass().getName(), e.getMessage()), e);
+ }
+ }
+ });
+ module.addSerializer(LocalDate.class, new JsonSerializer<LocalDate>() {
+ @Override
+ public void serialize(LocalDate localDate, JsonGenerator jsonGenerator,
+ SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+ jsonGenerator.writeString(dateFormatter.format(localDate));
+ }
+ });
+ module.addDeserializer(LocalDate.class, new JsonDeserializer<LocalDate>() {
+ @Override
+ public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException {
+ String string = parser.getText().trim();
+ if (string.length() == 0) {
+ return null;
+ }
+ try {
+ return LocalDate.parse(string, dateFormatter);
+ } catch (DateTimeException e) {
+ throw JsonMappingException.from(parser,
+ String.format("Failed to deserialize %s: (%s) %s",
+ handledType().getName(), e.getClass().getName(), e.getMessage()), e);
+ }
+ }
+ });
+ mapper.registerModule(module);
+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ return mapper;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/SwaggerConfig.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/SwaggerConfig.java b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/SwaggerConfig.java
new file mode 100644
index 0000000..0b0f9c6
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/SwaggerConfig.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * This will configure Swagger to produce an API for all of our REST endpoints.
+ */
+@Configuration
+@EnableSwagger2
+@EnableWebMvc
+public class SwaggerConfig {
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.any())
+ .paths(PathSelectors.any())
+ .build()
+ .directModelSubstitute(LocalDate.class, java.sql.Date.class)
+ .directModelSubstitute(LocalDateTime.class, java.util.Date.class);
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("Catalog Service")
+ .description("Maintains the audit event catalog")
+ .termsOfServiceUrl("http://logging.apache.org")
+ .contact("Apache Logging")
+ .license("1.0")
+ .licenseUrl("http://www.apache.org/licenses/")
+ .version("1.0")
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebAppInitializer.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebAppInitializer.java b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebAppInitializer.java
new file mode 100644
index 0000000..4e978c2
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebAppInitializer.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.config;
+
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+
+public class WebAppInitializer implements WebApplicationInitializer {
+ private static final String APPLICATION_NAME = "CatalogService";
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ servletContext.setInitParameter("applicationName", APPLICATION_NAME);
+ System.setProperty("applicationName", APPLICATION_NAME);
+ AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
+ rootContext.setDisplayName(APPLICATION_NAME);
+ rootContext.register(WebMvcAppContext.class);
+ servletContext.addListener(new ContextLoaderListener(rootContext));
+
+ ServletRegistration.Dynamic restServlet = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
+ restServlet.setLoadOnStartup(1);
+ restServlet.addMapping("/*");
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java
new file mode 100644
index 0000000..2eae80d
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.catalog.config;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+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.catalog.api.dao.CatalogDao;
+import org.apache.logging.log4j.catalog.git.dao.GitCatalogDao;
+import org.apache.logging.log4j.catalog.security.LocalAuthorizationInterceptor;
+import org.apache.logging.log4j.catalog.jpa.service.ConfigurationService;
+import org.eclipse.jgit.api.TransportConfigCallback;
+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.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.MessageSource;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+import org.springframework.web.servlet.view.JstlView;
+import org.thymeleaf.spring4.SpringTemplateEngine;
+import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
+import org.thymeleaf.spring4.view.ThymeleafView;
+import org.thymeleaf.spring4.view.ThymeleafViewResolver;
+import org.thymeleaf.templatemode.TemplateMode;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
+@Configuration
+@EnableWebMvc
+@EnableScheduling
+@ComponentScan(basePackages = {"org.apache.logging.log4j.catalog"})
+@PropertySource("classpath:catalog-${env:}config.properties")
+public class WebMvcAppContext extends WebMvcConfigurerAdapter implements ApplicationContextAware {
+
+ @Autowired
+ ConfigurationService configurationService;
+
+ private ApplicationContext applicationContext;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+ @Override
+ public void addResourceHandlers(final ResourceHandlerRegistry registry) {
+ super.addResourceHandlers(registry);
+ registry.addResourceHandler("/images/**").addResourceLocations("/images/");
+ registry.addResourceHandler("/css/**").addResourceLocations("/css/");
+ registry.addResourceHandler("/js/**").addResourceLocations("/js/");
+ registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
+ registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+ }
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("products").setViewName("products");
+ registry.addViewController("categories").setViewName("categories");
+ registry.addViewController("events").setViewName("events");
+ registry.addViewController("attributes").setViewName("attributes");
+ }
+
+ @Override
+ public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+ converters.add(jsonMessageConverter());
+ }
+
+
+ /*
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(localAuthorizationInterceptor())
+ .addPathPatterns("/**")
+ .excludePathPatterns("/swagger**")
+ .excludePathPatterns("/v2/api-docs**")
+ .excludePathPatterns("/configuration/security**")
+ .excludePathPatterns("/configuration/ui**")
+ .excludePathPatterns("/webjars/**");
+ }
+ */
+
+ @Bean
+ public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+ DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
+ proxyCreator.setProxyTargetClass(true);
+ return proxyCreator;
+ }
+
+ @Bean
+ public ViewResolver internalResourceViewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setViewClass(JstlView.class);
+ viewResolver.setPrefix("/WEB-INF/views/");
+ viewResolver.setSuffix(".jsp");
+ viewResolver.setOrder(10);
+ return viewResolver;
+ }
+
+ @Bean
+ public MessageSource messageSource() {
+ ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
+ messageSource.setBasename("messages");
+ return messageSource;
+ }
+
+ @Bean
+ public LocalAuthorizationInterceptor localAuthorizationInterceptor() {
+
+ return new LocalAuthorizationInterceptor(configurationService.getCatalogServiceAuthToken());
+ }
+
+ @Bean
+ public ObjectMapper objectMapper() {
+ return JsonObjectMapperFactory.createMapper();
+ }
+
+ @Bean
+ public MappingJackson2HttpMessageConverter jsonMessageConverter() {
+ return new MappingJackson2HttpMessageConverter(objectMapper());
+ }
+
+ @Value("${gitUserName")
+ private String gitUserName;
+
+ @Value("${gitPassword:#{null}}")
+ private String gitPassword;
+
+ @Value("${gitPassPhrase:#{null}}")
+ private String gitPassPhrase;
+
+ @Value("${localRepoUrl:#{null}}")
+ private String localRepoUrl;
+
+ @Value("${privateKeyPath:#{null}}")
+ private String privateKeyPath;
+
+ @Value("${remoteRepoUrl}")
+ private String remoteRepoUrl;
+
+ @Value("${remoteRepoCatalogPath:#{null}}")
+ private String remoteRepoCatalogPath;
+
+ @Bean
+ public CatalogDao catalogDao() {
+ GitCatalogDao dataSource = new GitCatalogDao();
+ if (isNotBlank(gitUserName) && isNotBlank(gitPassword)) {
+ dataSource.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassword));
+ }
+ TransportConfigCallback transportConfigCallback = new TransportConfigCallback() {
+ final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
+ @Override
+ protected JSch createDefaultJSch( FS fs ) throws JSchException {
+ JSch defaultJSch = super.createDefaultJSch( fs );
+ if (isNotBlank(privateKeyPath)) {
+ defaultJSch.addIdentity(privateKeyPath);
+ }
+ return defaultJSch;
+ }
+
+ @Override
+ protected void configure(OpenSshConfig.Host host, Session session) {
+ session.setConfig("StrictHostKeyChecking", "no");
+ if (isNotBlank(gitPassPhrase)) {
+ session.setUserInfo(new UserInfo() {
+ @Override
+ public String getPassphrase() {
+ return gitPassPhrase;
+ }
+
+ @Override
+ public String getPassword() {return null;}
+
+ @Override
+ public boolean promptPassword(String message) {return false;}
+
+ @Override
+ public boolean promptPassphrase(String message) {return true;}
+
+ @Override
+ public boolean promptYesNo(String message) {return false;}
+
+ @Override
+ public void showMessage(String message) {}
+ });
+
+ }
+ }
+ };
+ @Override
+ public void configure(Transport transport) {
+ SshTransport sshTransport = ( SshTransport )transport;
+ sshTransport.setSshSessionFactory( sshSessionFactory );
+
+ }
+ };
+ if (isNotBlank(localRepoUrl)) {
+ dataSource.setLocalRepoPath(localRepoUrl);
+ } else {
+ String localRepoPath = System.getProperty("java.io.tmpdir") + "/audit/catalog";
+ File file = new File(localRepoPath);
+ File parent = file.getParentFile();
+ parent.mkdirs();
+ dataSource.setLocalRepoPath(localRepoPath);
+ }
+ dataSource.setTransportConfigCallback(transportConfigCallback);
+ dataSource.setRemoteRepoUri(remoteRepoUrl);
+ if (isNotBlank(remoteRepoCatalogPath)) {
+ dataSource.setCatalogPath(remoteRepoCatalogPath);
+ }
+ return dataSource;
+ }
+
+ @Bean
+ public SpringResourceTemplateResolver templateResolver(){
+ // SpringResourceTemplateResolver automatically integrates with Spring's own
+ // resource resolution infrastructure, which is highly recommended.
+ SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
+ templateResolver.setApplicationContext(this.applicationContext);
+ templateResolver.setPrefix("/WEB-INF/templates/");
+ templateResolver.setSuffix(".html");
+ // HTML is the default value, added here for the sake of clarity.
+ templateResolver.setTemplateMode(TemplateMode.HTML);
+ // Template cache is true by default. Set to false if you want
+ // templates to be automatically updated when modified.
+ templateResolver.setCacheable(true);
+ return templateResolver;
+ }
+
+ @Bean
+ public SpringTemplateEngine templateEngine(){
+ // SpringTemplateEngine automatically applies SpringStandardDialect and
+ // enables Spring's own MessageSource message resolution mechanisms.
+ SpringTemplateEngine templateEngine = new SpringTemplateEngine();
+ templateEngine.setTemplateResolver(templateResolver());
+ // Enabling the SpringEL compiler with Spring 4.2.4 or newer can
+ // speed up execution in most scenarios, but might be incompatible
+ // with specific cases when expressions in one template are reused
+ // across different data types, so this flag is "false" by default
+ // for safer backwards compatibility.
+ templateEngine.setEnableSpringELCompiler(true);
+ return templateEngine;
+ }
+
+ @Bean
+ public ThymeleafViewResolver thymeleafViewResolver(){
+ ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
+ viewResolver.setTemplateEngine(templateEngine());
+ // NOTE 'order' and 'viewNames' are optional
+ viewResolver.setOrder(1);
+ viewResolver.setViewNames(new String[] {"products", "categories", "events", "attributes"});
+ return viewResolver;
+ }
+
+ @Bean
+ @Scope("prototype")
+ public ThymeleafView mainView() {
+ ThymeleafView view = new ThymeleafView("index"); // templateName = 'main'
+ view.setStaticVariables(
+ Collections.singletonMap("footer", "The ACME Fruit Company"));
+ return view;
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/controller/AttributeController.java
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/controller/AttributeController.java b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/controller/AttributeController.java
new file mode 100644
index 0000000..bd93a00
--- /dev/null
+++ b/log4j-catalog/log4j-catalog-war/src/main/java/org/apache/logging/log4j/catalog/controller/AttributeController.java
@@ -0,0 +1,183 @@
+package org.apache.logging.log4j.catalog.controller;
+
+import javax.annotation.PostConstruct;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.api.Attribute;
+import org.apache.logging.log4j.catalog.api.Constraint;
+import org.apache.logging.log4j.catalog.api.ListResponse;
+import org.apache.logging.log4j.catalog.api.plugins.ConstraintPlugins;
+import org.apache.logging.log4j.catalog.jpa.converter.AttributeConverter;
+import org.apache.logging.log4j.catalog.jpa.converter.AttributeModelConverter;
+import org.apache.logging.log4j.catalog.jpa.model.AttributeModel;
+import org.apache.logging.log4j.catalog.jpa.model.ConstraintModel;
+import org.apache.logging.log4j.catalog.jpa.service.AttributeService;
+import org.modelmapper.ModelMapper;
+import org.modelmapper.TypeToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Catalog Product controller
+ */
+
+@RequestMapping(value = "/api/attributes")
+@RestController
+public class AttributeController {
+ private static final Logger LOGGER = LogManager.getLogger();
+ private static ConstraintPlugins constraintPlugins = ConstraintPlugins.getInstance();
+
+ private ModelMapper modelMapper = new ModelMapper();
+
+ @Autowired
+ private AttributeService attributeService;
+
+ @Autowired
+ private AttributeModelConverter attributeModelConverter;
+
+ @Autowired
+ private AttributeConverter attributeConverter;
+
+ @PostConstruct
+ public void init() {
+ modelMapper.addConverter(attributeModelConverter);
+ }
+
+ @PostMapping(value = "/list")
+ public ResponseEntity<Map<String, Object>> attributeList(@RequestParam(value="jtStartIndex", required=false) Integer startIndex,
+ @RequestParam(value="jtPageSize", required=false) Integer pageSize,
+ @RequestParam(value="jtSorting", required=false) String sorting) {
+ Type listType = new TypeToken<List<Attribute>>() {}.getType();
+ Map<String, Object> response = new HashMap<>();
+ try {
+ List<Attribute> attributes = null;
+ if (startIndex == null || pageSize == null) {
+ attributes = modelMapper.map(attributeService.getAttributes(), listType);
+ } else {
+ int startPage = 0;
+ if (startIndex > 0) {
+ startPage = startIndex / pageSize;
+ }
+ String sortColumn = "name";
+ String sortDirection = "ASC";
+ if (sorting != null) {
+ String[] sortInfo = sorting.split(" ");
+ sortColumn = sortInfo[0];
+ if (sortInfo.length > 0) {
+ sortDirection = sortInfo[1];
+ }
+ }
+ attributes = modelMapper.map(attributeService.getAttributes(startPage, pageSize, sortColumn, sortDirection), listType);
+ }
+ if (attributes == null) {
+ attributes = new ArrayList<>();
+ }
+ response.put("Result", "OK");
+ response.put("Records", attributes);
+ } catch (Exception ex) {
+ response.put("Result", "FAILURE");
+ }
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ @PostMapping(value = "/create")
+ public ResponseEntity<Map<String, Object>> createAttribute(@RequestBody Attribute attribute) {
+ Map<String, Object> response = new HashMap<>();
+ try {
+ AttributeModel model = attributeConverter.convert(attribute);
+ model = attributeService.saveAttribute(model);
+ Attribute result = attributeModelConverter.convert(model);
+ response.put("Result", "OK");
+ response.put("Records", result);
+ } catch (Exception ex) {
+ response.put("Result", "FAILURE");
+ }
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ @PostMapping(value = "/update")
+ public ResponseEntity<Map<String, Object>> updateAttribute(@RequestBody Attribute attribute) {
+ Map<String, Object> response = new HashMap<>();
+ try {
+ AttributeModel model = attributeConverter.convert(attribute);
+ model = attributeService.saveAttribute(model);
+ Attribute result = attributeModelConverter.convert(model);
+ response.put("Result", "OK");
+ response.put("Records", result);
+ } catch (Exception ex) {
+ response.put("Result", "FAILURE");
+ }
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ @PostMapping(value = "/delete")
+ public ResponseEntity<Map<String, Object>> deleteAttribute(@RequestBody Attribute attribute) {
+ Map<String, Object> response = new HashMap<>();
+ try {
+ attributeService.deleteAttribute(attribute.getId());
+ response.put("Result", "OK");
+ } catch (Exception ex) {
+ response.put("Result", "FAILURE");
+ }
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ @GetMapping
+ public ResponseEntity<ListResponse<String>> getAttributeNames() {
+ List<AttributeModel> attributes = attributeService.getAttributes();
+ List<String> attributeNames;
+ if (attributes != null) {
+ attributeNames = new ArrayList<>(attributes.size());
+ for (AttributeModel model : attributes) {
+ attributeNames.add(model.getName());
+ }
+ } else {
+ attributeNames = new ArrayList<>();
+ }
+ ListResponse<String> response = new ListResponse<>();
+ response.setResult("OK");
+ response.setData(attributeNames);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ @PostMapping(value = "/constraints")
+ public ResponseEntity<Map<String, Object>> constraintList(@RequestParam("attributeId") Long attributeId) {
+ Type listType = new TypeToken<List<Constraint>>() {}.getType();
+ Map<String, Object> response = new HashMap<>();
+ try {
+ Optional<AttributeModel> optional = attributeService.getAttribute(attributeId);
+ List<Constraint> constraints = new ArrayList<>();
+ if (optional.isPresent()) {
+ Set<ConstraintModel> constraintModels = optional.get().getConstraints();
+ if (constraintModels != null) {
+ for (ConstraintModel constraintModel : constraintModels) {
+ Constraint constraint = new Constraint();
+ constraint.setConstraintType(constraintPlugins.findByName(constraintModel.getConstraintType()));
+ constraint.setValue(constraintModel.getValue());
+ constraints.add(constraint);
+ }
+ }
+ response.put("Result", "OK");
+ response.put("Records", constraints);
+ }
+ } catch (Exception ex) {
+ response.put("Result", "FAILURE");
+ }
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+}