Initial commit
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/f0884aeb Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/tree/f0884aeb Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/diff/f0884aeb Branch: refs/heads/master Commit: f0884aeb8414960e409ef0e2a09c1d2712e6d3e6 Parents: bdfc809 Author: Ralph Goers <[email protected]> Authored: Sat Sep 2 19:18:04 2017 -0700 Committer: Ralph Goers <[email protected]> Committed: Sat Sep 2 19:18:04 2017 -0700 ---------------------------------------------------------------------- NOTICE.txt | 5 +- RELEASE-NOTES.md | 17 + log4j-audit-distribution/pom.xml | 273 + log4j-audit-distribution/src/assembly/bin.xml | 59 + log4j-audit-distribution/src/assembly/src.xml | 81 + log4j-audit/log4j-audit-api/pom.xml | 86 + .../log4j/audit/AbstractEventLogger.java | 206 + .../logging/log4j/audit/ActivityLogger.java | 49 + .../apache/logging/log4j/audit/AuditEvent.java | 41 + .../log4j/audit/AuditExceptionHandler.java | 33 + .../apache/logging/log4j/audit/AuditLogger.java | 50 + .../logging/log4j/audit/AuditMessage.java | 58 + .../logging/log4j/audit/LogEventFactory.java | 385 + .../log4j/audit/annotation/Constraint.java | 33 + .../log4j/audit/annotation/Constraints.java | 31 + .../log4j/audit/annotation/MaxLength.java | 31 + .../log4j/audit/annotation/RequestContext.java | 42 + .../annotation/RequestContextConstraints.java | 31 + .../log4j/audit/annotation/Required.java | 30 + .../log4j/audit/catalog/CatalogManager.java | 42 + .../log4j/audit/catalog/CatalogManagerImpl.java | 150 + .../logging/log4j/audit/constant/Column.java | 102 + .../log4j/audit/constant/Environment.java | 45 + .../log4j/audit/constant/QueryParameter.java | 41 + .../logging/log4j/audit/dto/AuditDto.java | 87 + .../log4j/audit/exception/AuditException.java | 37 + .../audit/generator/AccessorDefinition.java | 153 + .../log4j/audit/generator/ClassGenerator.java | 355 + .../log4j/audit/generator/Constants.java | 25 + .../audit/generator/ConstructorDefinition.java | 122 + .../audit/generator/InterfacesGenerator.java | 335 + .../log4j/audit/generator/MethodDefinition.java | 334 + .../log4j/audit/generator/Parameter.java | 77 + .../audit/generator/VariableDefinition.java | 149 + .../logging/log4j/audit/layout/AuditLayout.java | 20 + .../audit/util/JsonObjectMapperFactory.java | 164 + .../logging/log4j/audit/util/NamingUtils.java | 79 + .../logging/log4j/audit/util/StringUtil.java | 31 + .../logging/log4j/audit/AuditLoggerTest.java | 115 + .../logging/log4j/audit/TransferTest.java | 162 + .../log4j/audit/catalog/CatalogManagerTest.java | 35 + .../audit/catalog/StringCatalogReader.java | 228 + .../logging/log4j/audit/event/Transfer.java | 60 + .../generator/TestInterfacesGenerator.java | 68 + .../log4j/audit/util/NamingUtilsTest.java | 37 + .../resources/InterfacesGeneratorContext.xml | 64 + .../src/test/resources/catalog.zip | Bin 0 -> 964 bytes .../resources/interfacesGenerator.properties | 14 + .../src/test/resources/log4j2-test.xml | 41 + log4j-audit/log4j-audit-api/testCatalog.json | 193 + log4j-audit/log4j-audit-maven-plugin/pom.xml | 156 + .../src/it/default-generate/pom.xml | 154 + .../src/main/resources/catalog.json | 193 + .../src/it/default-generate/verify.groovy | 19 + .../src/it/settings.xml | 54 + .../logging/log4j/audit/plugin/AuditMojo.java | 121 + .../src/main/resources/log4j2.xml | 29 + log4j-audit/log4j-audit-war/pom.xml | 187 + .../logging/log4j/audit/service/Versions.java | 26 + .../config/ApplicationConfiguration.java | 23 + .../service/config/ConfigurationService.java | 33 + .../audit/service/config/SwaggerConfig.java | 63 + .../audit/service/config/WebAppInitializer.java | 48 + .../audit/service/config/WebMvcAppContext.java | 176 + .../service/controller/AuditController.java | 61 + .../RestResponseEntityExceptionHandler.java | 55 + .../security/LocalAuthorizationInterceptor.java | 57 + .../src/main/resources/log4j2.xml | 80 + log4j-audit/pom.xml | 33 + log4j-catalog/log4j-catalog-api/pom.xml | 105 + .../logging/log4j/catalog/api/Attribute.java | 315 + .../logging/log4j/catalog/api/CatalogData.java | 115 + .../log4j/catalog/api/CatalogReader.java | 72 + .../log4j/catalog/api/CatalogWriter.java | 20 + .../logging/log4j/catalog/api/Category.java | 154 + .../logging/log4j/catalog/api/Constraint.java | 69 + .../log4j/catalog/api/ConstraintType.java | 45 + .../logging/log4j/catalog/api/DataType.java | 60 + .../apache/logging/log4j/catalog/api/Event.java | 185 + .../log4j/catalog/api/EventAttribute.java | 67 + .../logging/log4j/catalog/api/ListResponse.java | 43 + .../logging/log4j/catalog/api/Product.java | 151 + .../apache/logging/log4j/catalog/api/Type.java | 27 + .../logging/log4j/catalog/api/Versions.java | 26 + .../annotation/ConditionOnPropertyExists.java | 37 + .../api/annotation/PropertyExistsCondition.java | 38 + .../catalog/api/dao/AbstractCatalogReader.java | 77 + .../log4j/catalog/api/dao/CatalogDao.java | 64 + .../catalog/api/dao/ClassPathCatalogReader.java | 89 + .../catalog/api/dao/FileCatalogReader.java | 90 + .../catalog/api/dao/JsonCatalogReader.java | 67 + .../catalog/api/exception/CatalogException.java | 41 + .../exception/CatalogModificationException.java | 41 + .../api/exception/CatalogNotFoundException.java | 41 + .../api/exception/CatalogReadException.java | 41 + .../api/exception/CatalogWriteException.java | 41 + .../exception/ConstraintCreationException.java | 41 + .../ConstraintValidationException.java | 41 + .../api/exception/DuplicateNameException.java | 41 + .../exception/InvalidEnvironmentException.java | 41 + .../api/exception/InvalidSiteException.java | 41 + .../api/exception/NameNotFoundException.java | 41 + .../logging/log4j/catalog/api/package-info.java | 19 + .../plugins/CaseInsensitiveEnumConstraint.java | 44 + .../catalog/api/plugins/ConstraintPlugins.java | 105 + .../api/plugins/ConstraintTypeDeserializer.java | 54 + .../api/plugins/ConstraintTypeSerializer.java | 51 + .../catalog/api/plugins/EnumConstraint.java | 44 + .../api/plugins/MaxLengthConstraint.java | 58 + .../catalog/api/plugins/MaxValueConstraint.java | 61 + .../api/plugins/MinLengthConstraint.java | 58 + .../catalog/api/plugins/MinValueConstraint.java | 61 + .../catalog/api/plugins/PatternConstraint.java | 41 + .../catalog/api/service/CatalogService.java | 26 + .../log4j/catalog/api/util/StringUtils.java | 35 + log4j-catalog/log4j-catalog-git/pom.xml | 134 + .../log4j/catalog/git/config/ServiceConfig.java | 22 + .../log4j/catalog/git/config/package-info.java | 19 + .../log4j/catalog/git/dao/GitCatalogDao.java | 202 + .../log4j/catalog/git/dao/GitCatalogData.java | 48 + .../log4j/catalog/git/dao/package-info.java | 19 + .../logging/log4j/catalog/git/package-info.java | 19 + .../logging/log4j/catalog/git/CatalogTest.java | 108 + .../git/config/ApplicationConfiguration.java | 65 + .../src/test/resources/log4j2.xml | 48 + log4j-catalog/log4j-catalog-jpa/pom.xml | 257 + .../jpa/config/ApplicationConfiguration.java | 34 + .../jpa/config/EclipseLinkDataSourceConfig.java | 73 + .../jpa/config/HibernatgeDataSourceConfig.java | 69 + .../log4j/catalog/jpa/config/package-info.java | 19 + .../jpa/converter/AttributeConverter.java | 88 + .../jpa/converter/AttributeModelConverter.java | 62 + .../jpa/converter/BooleanToStringConverter.java | 37 + .../jpa/converter/CategoryConverter.java | 56 + .../jpa/converter/CategoryModelConverter.java | 49 + .../jpa/converter/DataTypeConverter.java | 38 + .../jpa/converter/DateTimeConverter.java | 41 + .../catalog/jpa/converter/EventConverter.java | 96 + .../jpa/converter/EventModelConverter.java | 54 + .../catalog/jpa/converter/ProductConverter.java | 56 + .../jpa/converter/ProductModelConverter.java | 49 + .../catalog/jpa/converter/package-info.java | 19 + .../catalog/jpa/dao/AttributeRepository.java | 22 + .../log4j/catalog/jpa/dao/BaseRepository.java | 40 + .../catalog/jpa/dao/CategoryRepository.java | 25 + .../catalog/jpa/dao/ConstraintRepository.java | 23 + .../log4j/catalog/jpa/dao/EventRepository.java | 22 + .../jpa/dao/PagingAndSortingRepository.java | 31 + .../catalog/jpa/dao/ProductRepository.java | 22 + .../log4j/catalog/jpa/dao/package-info.java | 19 + .../exception/InvalidEnvironmentException.java | 41 + .../jpa/exception/InvalidSiteException.java | 41 + .../log4j/catalog/jpa/model/AttributeModel.java | 323 + .../log4j/catalog/jpa/model/CategoryModel.java | 168 + .../catalog/jpa/model/ConstraintModel.java | 85 + .../catalog/jpa/model/EventAttributeModel.java | 119 + .../log4j/catalog/jpa/model/EventModel.java | 232 + .../log4j/catalog/jpa/model/ProductModel.java | 152 + .../log4j/catalog/jpa/model/package-info.java | 19 + .../logging/log4j/catalog/jpa/package-info.java | 19 + .../AbstractPagingAndSortingService.java | 44 + .../catalog/jpa/service/AttributeService.java | 33 + .../jpa/service/AttributeServiceImpl.java | 67 + .../catalog/jpa/service/CatalogServiceImpl.java | 121 + .../catalog/jpa/service/CategoryService.java | 33 + .../jpa/service/CategoryServiceImpl.java | 68 + .../jpa/service/ConfigurationService.java | 31 + .../catalog/jpa/service/ConstraintService.java | 33 + .../jpa/service/ConstraintServiceImpl.java | 67 + .../log4j/catalog/jpa/service/EventService.java | 35 + .../catalog/jpa/service/EventServiceImpl.java | 80 + .../catalog/jpa/service/ProductService.java | 30 + .../catalog/jpa/service/ProductServiceImpl.java | 68 + .../src/main/resources/sql/schema.sql | 121 + .../logging/log4j/catalog/jpa/CatalogTest.java | 203 + .../src/test/resources/log4j2.xml | 45 + .../src/test/resources/sql/afterTestRun.sql | 24 + .../src/test/resources/sql/beforeTestRun.sql | 58 + log4j-catalog/log4j-catalog-war/pom.xml | 182 + .../catalog/config/JsonObjectMapperFactory.java | 150 + .../log4j/catalog/config/SwaggerConfig.java | 63 + .../log4j/catalog/config/WebAppInitializer.java | 44 + .../log4j/catalog/config/WebMvcAppContext.java | 312 + .../catalog/controller/AttributeController.java | 183 + .../catalog/controller/CatalogController.java | 399 + .../catalog/controller/CategoryController.java | 130 + .../controller/ConstraintController.java | 86 + .../catalog/controller/EventController.java | 158 + .../catalog/controller/ProductController.java | 130 + .../RestResponseEntityExceptionHandler.java | 55 + .../RequestContextHeaderInterceptor.java | 41 + .../security/LocalAuthorizationInterceptor.java | 54 + .../catalog/service/CatalogInitializer.java | 99 + .../CatalogService/application.properties | 2 + .../resources/CatalogService/lab.properties | 2 + .../src/main/resources/log4j2.xml | 43 + .../webapp/WEB-INF/templates/attributes.html | 28 + .../webapp/WEB-INF/templates/categories.html | 27 + .../main/webapp/WEB-INF/templates/events.html | 28 + .../main/webapp/WEB-INF/templates/products.html | 27 + .../main/webapp/WEB-INF/templates/template.html | 25 + .../src/main/webapp/css/app.css | 154 + .../src/main/webapp/images/attributes.png | Bin 0 -> 1981 bytes .../src/main/webapp/images/constraint.png | Bin 0 -> 2586 bytes .../log4j-catalog-war/src/main/webapp/js/app.js | 43 + .../src/main/webapp/js/attributes.js | 348 + .../src/main/webapp/js/categories.js | 241 + .../src/main/webapp/js/events.js | 253 + .../src/main/webapp/js/jquery-1.12.4.min.js | 5 + .../src/main/webapp/js/jquery-2.2.4.min.js | 4 + .../src/main/webapp/js/jquery-3.2.1.min.js | 4 + .../main/webapp/js/jquery-ui-1.12.1/AUTHORS.txt | 333 + .../main/webapp/js/jquery-ui-1.12.1/LICENSE.txt | 43 + .../jquery-ui-1.12.1/external/jquery/jquery.js | 11008 ++++++++++ .../images/ui-icons_444444_256x240.png | Bin 0 -> 7006 bytes .../images/ui-icons_555555_256x240.png | Bin 0 -> 7074 bytes .../images/ui-icons_777620_256x240.png | Bin 0 -> 4676 bytes .../images/ui-icons_777777_256x240.png | Bin 0 -> 7013 bytes .../images/ui-icons_cc0000_256x240.png | Bin 0 -> 4632 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6313 bytes .../main/webapp/js/jquery-ui-1.12.1/index.html | 559 + .../webapp/js/jquery-ui-1.12.1/jquery-ui.css | 1312 ++ .../webapp/js/jquery-ui-1.12.1/jquery-ui.js | 18706 +++++++++++++++++ .../js/jquery-ui-1.12.1/jquery-ui.min.css | 7 + .../webapp/js/jquery-ui-1.12.1/jquery-ui.min.js | 13 + .../js/jquery-ui-1.12.1/jquery-ui.structure.css | 886 + .../jquery-ui.structure.min.css | 5 + .../js/jquery-ui-1.12.1/jquery-ui.theme.css | 443 + .../js/jquery-ui-1.12.1/jquery-ui.theme.min.css | 5 + .../webapp/js/jquery-ui-1.12.1/package.json | 74 + .../jquery.jtable.aspnetpagemethods.js | 150 + .../jquery.jtable.aspnetpagemethods.min.js | 27 + .../webapp/js/jtable.2.4.0/external/json2.js | 486 + .../js/jtable.2.4.0/external/json2.min.js | 8 + .../webapp/js/jtable.2.4.0/jquery.jtable.js | 5021 +++++ .../webapp/js/jtable.2.4.0/jquery.jtable.min.js | 157 + .../localization/jquery.jtable.bd.js | 30 + .../localization/jquery.jtable.ca.js | 30 + .../localization/jquery.jtable.cz.js | 30 + .../localization/jquery.jtable.de.js | 30 + .../localization/jquery.jtable.es.js | 30 + .../localization/jquery.jtable.fa.js | 30 + .../localization/jquery.jtable.fr.js | 30 + .../localization/jquery.jtable.hr.js | 30 + .../localization/jquery.jtable.hu.js | 30 + .../localization/jquery.jtable.id.js | 31 + .../localization/jquery.jtable.it.js | 30 + .../localization/jquery.jtable.lt.js | 30 + .../localization/jquery.jtable.nl-NL.js | 30 + .../localization/jquery.jtable.no.js | 30 + .../localization/jquery.jtable.pl.js | 30 + .../localization/jquery.jtable.pt-BR.js | 30 + .../localization/jquery.jtable.pt-PT.js | 29 + .../localization/jquery.jtable.ro.js | 30 + .../localization/jquery.jtable.ru.js | 31 + .../localization/jquery.jtable.se.js | 30 + .../localization/jquery.jtable.tr.js | 30 + .../localization/jquery.jtable.vi.js | 28 + .../localization/jquery.jtable.zh-CN.js | 30 + .../js/jtable.2.4.0/themes/basic/close.png | Bin 0 -> 3350 bytes .../js/jtable.2.4.0/themes/basic/column-asc.png | Bin 0 -> 362 bytes .../jtable.2.4.0/themes/basic/column-desc.png | Bin 0 -> 349 bytes .../themes/basic/column-sortable.png | Bin 0 -> 347 bytes .../js/jtable.2.4.0/themes/basic/delete.png | Bin 0 -> 150 bytes .../js/jtable.2.4.0/themes/basic/edit.png | Bin 0 -> 590 bytes .../jtable.2.4.0/themes/basic/jtable_basic.css | 282 + .../jtable.2.4.0/themes/basic/jtable_basic.less | 83 + .../themes/basic/jtable_basic.min.css | 1 + .../js/jtable.2.4.0/themes/jqueryui/add.png | Bin 0 -> 482 bytes .../jtable.2.4.0/themes/jqueryui/bg-thead.png | Bin 0 -> 2811 bytes .../js/jtable.2.4.0/themes/jqueryui/close.png | Bin 0 -> 1217 bytes .../jtable.2.4.0/themes/jqueryui/column-asc.png | Bin 0 -> 362 bytes .../themes/jqueryui/column-desc.png | Bin 0 -> 349 bytes .../themes/jqueryui/column-sortable.png | Bin 0 -> 347 bytes .../js/jtable.2.4.0/themes/jqueryui/delete.png | Bin 0 -> 150 bytes .../js/jtable.2.4.0/themes/jqueryui/edit.png | Bin 0 -> 590 bytes .../themes/jqueryui/jtable_jqueryui.css | 398 + .../themes/jqueryui/jtable_jqueryui.less | 296 + .../themes/jqueryui/jtable_jqueryui.min.css | 1 + .../js/jtable.2.4.0/themes/jqueryui/loading.gif | Bin 0 -> 723 bytes .../jtable.2.4.0/themes/jtable_theme_base.less | 524 + .../js/jtable.2.4.0/themes/lightcolor/add.png | Bin 0 -> 482 bytes .../jtable.2.4.0/themes/lightcolor/bg-thead.png | Bin 0 -> 2811 bytes .../themes/lightcolor/blue/jtable.css | 521 + .../themes/lightcolor/blue/jtable.less | 90 + .../themes/lightcolor/blue/jtable.min.css | 1 + .../themes/lightcolor/blue/loading.gif | Bin 0 -> 723 bytes .../js/jtable.2.4.0/themes/lightcolor/close.png | Bin 0 -> 1217 bytes .../themes/lightcolor/column-asc.png | Bin 0 -> 362 bytes .../themes/lightcolor/column-desc.png | Bin 0 -> 349 bytes .../themes/lightcolor/column-sortable.png | Bin 0 -> 347 bytes .../jtable.2.4.0/themes/lightcolor/delete.png | Bin 0 -> 150 bytes .../js/jtable.2.4.0/themes/lightcolor/edit.png | Bin 0 -> 590 bytes .../themes/lightcolor/gray/jtable.css | 521 + .../themes/lightcolor/gray/jtable.less | 90 + .../themes/lightcolor/gray/jtable.min.css | 1 + .../themes/lightcolor/gray/loading.gif | Bin 0 -> 723 bytes .../themes/lightcolor/green/jtable.css | 521 + .../themes/lightcolor/green/jtable.less | 90 + .../themes/lightcolor/green/jtable.min.css | 1 + .../themes/lightcolor/green/loading.gif | Bin 0 -> 723 bytes .../lightcolor/jtable_lightcolor_base.less | 329 + .../themes/lightcolor/orange/jtable.css | 521 + .../themes/lightcolor/orange/jtable.less | 90 + .../themes/lightcolor/orange/jtable.min.css | 1 + .../themes/lightcolor/orange/loading.gif | Bin 0 -> 723 bytes .../themes/lightcolor/red/jtable.css | 521 + .../themes/lightcolor/red/jtable.less | 90 + .../themes/lightcolor/red/jtable.min.css | 1 + .../themes/lightcolor/red/loading.gif | Bin 0 -> 723 bytes .../webapp/js/jtable.2.4.0/themes/metro/add.png | Bin 0 -> 482 bytes .../jtable.2.4.0/themes/metro/blue/jtable.css | 495 + .../jtable.2.4.0/themes/metro/blue/jtable.less | 11 + .../themes/metro/blue/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/blue/loading.gif | Bin 0 -> 404 bytes .../jtable.2.4.0/themes/metro/brown/jtable.css | 495 + .../jtable.2.4.0/themes/metro/brown/jtable.less | 11 + .../themes/metro/brown/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/brown/loading.gif | Bin 0 -> 404 bytes .../js/jtable.2.4.0/themes/metro/close.png | Bin 0 -> 3350 bytes .../js/jtable.2.4.0/themes/metro/column-asc.png | Bin 0 -> 320 bytes .../jtable.2.4.0/themes/metro/column-desc.png | Bin 0 -> 311 bytes .../themes/metro/column-sortable.png | Bin 0 -> 314 bytes .../themes/metro/crimson/jtable.css | 495 + .../themes/metro/crimson/jtable.less | 11 + .../themes/metro/crimson/jtable.min.css | 1 + .../themes/metro/crimson/loading.gif | Bin 0 -> 404 bytes .../themes/metro/darkgray/jtable.css | 495 + .../themes/metro/darkgray/jtable.less | 11 + .../themes/metro/darkgray/jtable.min.css | 1 + .../themes/metro/darkgray/loading.gif | Bin 0 -> 404 bytes .../themes/metro/darkorange/jtable.css | 495 + .../themes/metro/darkorange/jtable.less | 11 + .../themes/metro/darkorange/jtable.min.css | 1 + .../themes/metro/darkorange/loading.gif | Bin 0 -> 404 bytes .../js/jtable.2.4.0/themes/metro/delete.png | Bin 0 -> 3167 bytes .../js/jtable.2.4.0/themes/metro/edit.png | Bin 0 -> 3359 bytes .../jtable.2.4.0/themes/metro/green/jtable.css | 495 + .../jtable.2.4.0/themes/metro/green/jtable.less | 11 + .../themes/metro/green/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/green/loading.gif | Bin 0 -> 404 bytes .../themes/metro/jtable_metro_base.css | 48 + .../themes/metro/jtable_metro_base.less | 439 + .../themes/metro/jtable_metro_base.min.css | 1 + .../themes/metro/lightgray/jtable.css | 495 + .../themes/metro/lightgray/jtable.less | 11 + .../themes/metro/lightgray/jtable.min.css | 1 + .../themes/metro/lightgray/loading.gif | Bin 0 -> 404 bytes .../jtable.2.4.0/themes/metro/pink/jtable.css | 495 + .../jtable.2.4.0/themes/metro/pink/jtable.less | 11 + .../themes/metro/pink/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/pink/loading.gif | Bin 0 -> 404 bytes .../jtable.2.4.0/themes/metro/purple/jtable.css | 495 + .../themes/metro/purple/jtable.less | 11 + .../themes/metro/purple/jtable.min.css | 1 + .../themes/metro/purple/loading.gif | Bin 0 -> 404 bytes .../js/jtable.2.4.0/themes/metro/red/jtable.css | 495 + .../jtable.2.4.0/themes/metro/red/jtable.less | 11 + .../themes/metro/red/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/red/loading.gif | Bin 0 -> 404 bytes .../src/main/webapp/js/products.js | 241 + log4j-catalog/pom.xml | 36 + pom.xml | 1314 ++ 363 files changed, 69216 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/NOTICE.txt ---------------------------------------------------------------------- diff --git a/NOTICE.txt b/NOTICE.txt index 3b3bcf3..a655af0 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,5 +1,6 @@ -Apache Log4j -Copyright 2016 Apache Software Foundation +Apache Log4j Audit +Copyright 2017 Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). + http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/RELEASE-NOTES.md ---------------------------------------------------------------------- diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100644 index 0000000..af0c9e1 --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,17 @@ +# Apache Log4j Audit 1.0.0 Release Notes + +This is the initial release of Log4j Audit. + +## GA Release 1.0.0 + +Changes in this version include: + + +--- + +Apache Log4j Audit 1.0.0 requires a minimum of Java 8 to build and run. + +For complete information on Apache Log4j Audit, including instructions on how to submit bug +reports, patches, or suggestions for improvement, see the Apache Apache Log4j Audit website: + +https://logging.apache.org/log4j-audit/ \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit-distribution/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-audit-distribution/pom.xml b/log4j-audit-distribution/pom.xml new file mode 100644 index 0000000..38a9e80 --- /dev/null +++ b/log4j-audit-distribution/pom.xml @@ -0,0 +1,273 @@ +<?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. +--> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit</artifactId> + <version>1.0.0-SNAPSHOT</version> + <relativePath>../</relativePath> + </parent> + <artifactId>log4j-audit-distribution</artifactId> + <packaging>pom</packaging> + <name>Log4j Audit Distribution</name> + <description>The Apache Log4j Audit distribution archives.</description> + <dependencies> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-api</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-api</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-maven-plugin</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-maven-plugin</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-maven-plugin</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-war</artifactId> + <version>${project.version}</version> + <type>war</type> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-war</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit-war</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-api</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-api</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-client</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-client</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-client</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-git</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-git</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-git</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-impl</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-impl</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-impl</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-jpa</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-jpa</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-jpa</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-redis</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-redis</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-redis</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-war</artifactId> + <type>war</type> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-war</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-war</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + + <execution> + <id>log4j2-source-release-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <finalName>apache-log4j-audit-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/src.xml</descriptor> + </descriptors> + <tarLongFileMode>gnu</tarLongFileMode> + </configuration> + </execution> + <execution> + <id>binary</id> + <configuration> + <finalName>apache-log4j-audit-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/bin.xml</descriptor> + </descriptors> + <tarLongFileMode>gnu</tarLongFileMode> + </configuration> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + </execution> + <!-- <execution> + <id>osgi-binary</id> + <configuration> + <finalName>apache-log4j-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/osgi-bin.xml</descriptor> + </descriptors> + <tarLongFileMode>gnu</tarLongFileMode> + </configuration> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + </execution> --> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.0</version> + <configuration> + <skip>true</skip> + <skipDeploy>true</skipDeploy> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <version>2.8.2</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit-distribution/src/assembly/bin.xml ---------------------------------------------------------------------- diff --git a/log4j-audit-distribution/src/assembly/bin.xml b/log4j-audit-distribution/src/assembly/bin.xml new file mode 100644 index 0000000..6cee98e --- /dev/null +++ b/log4j-audit-distribution/src/assembly/bin.xml @@ -0,0 +1,59 @@ +<?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. +--> +<assembly> + <id>bin</id> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + <baseDirectory>apache-log4j-audit-${project.version}-bin</baseDirectory> + <includeSiteDirectory>false</includeSiteDirectory> + <moduleSets> + <moduleSet> + <useAllReactorProjects>true</useAllReactorProjects> + </moduleSet> + </moduleSets> + <dependencySets> + <dependencySet> + <includes> + <include>org.apache.logging.log4j:log4j-*</include> + </includes> + <outputDirectory></outputDirectory> + <unpack>false</unpack> + </dependencySet> + </dependencySets> + + <fileSets> + <fileSet> + <directory>..</directory> + <includes> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + </includes> + </fileSet> + </fileSets> + <files> + <file> + <source>../RELEASE-NOTES.md</source> + <outputDirectory>.</outputDirectory> + <destName>RELEASE-NOTES.md</destName> + </file> + </files> +</assembly> http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit-distribution/src/assembly/src.xml ---------------------------------------------------------------------- diff --git a/log4j-audit-distribution/src/assembly/src.xml b/log4j-audit-distribution/src/assembly/src.xml new file mode 100644 index 0000000..b38a99d --- /dev/null +++ b/log4j-audit-distribution/src/assembly/src.xml @@ -0,0 +1,81 @@ +<?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. +--> + +<assembly> + <id>src</id> + <formats> + <format>zip</format> + <format>tar.gz</format> + </formats> + <baseDirectory>apache-log4j-${project.version}-src</baseDirectory> + <fileSets> + <!-- main project directory structure --> + <fileSet> + <directory>..</directory> + <outputDirectory>/</outputDirectory> + <useDefaultExcludes>true</useDefaultExcludes> + <excludes> + <exclude>**/flume-og/**</exclude> + <!-- build output --> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/).*${project.build.directory}.*]</exclude> + + <!-- NOTE: Most of the following excludes should not be required + if the standard release process is followed. This is because the + release plugin checks out project sources into a location like + target/checkout, then runs the build from there. The result is + a source-release archive that comes from a pretty clean directory + structure. + + HOWEVER, if the release plugin is configured to run extra goals + or generate a project website, it's definitely possible that some + of these files will be present. So, it's safer to exclude them. + --> + + <!-- IDEs --> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?maven-eclipse\.xml]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.project]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.classpath]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iws]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.ipr]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iml]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.idea(/.*)?]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.settings(/.*)?]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?Vagrantfile(/.*)?]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?Dockerfile(/.*)?]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.externalToolBuilders(/.*)?]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.deployables(/.*)?]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.wtpmodules(/.*)?]</exclude> + + <!-- misc --> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?cobertura\.ser]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?doap_vfs\.rdf]</exclude> + + <!-- release-plugin temp files --> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\.xml\.releaseBackup]</exclude> + <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?release\.properties]</exclude> + </excludes> + </fileSet> + <!-- license, readme, etc. calculated at build time + <fileSet> + <directory>${project.build.directory}/maven-shared-archive-resources/META-INF</directory> + <outputDirectory>/</outputDirectory> + </fileSet> --> + </fileSets> +</assembly> http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/pom.xml b/log4j-audit/log4j-audit-api/pom.xml new file mode 100644 index 0000000..f44407a --- /dev/null +++ b/log4j-audit/log4j-audit-api/pom.xml @@ -0,0 +1,86 @@ +<?xml version="1.0"?> +<!-- + ~ 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. + --> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-audit</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + <artifactId>log4j-audit-api</artifactId> + <packaging>jar</packaging> + <name>Log4j Audit API</name> + + <dependencies> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-catalog-api</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.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.datatype</groupId> + <artifactId>jackson-datatype-jsr310</artifactId> + </dependency> + <dependency> + <groupId>net.sf.jopt-simple</groupId> + <artifactId>jopt-simple</artifactId> + </dependency> + <!-- Test Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-jcl</artifactId> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>3.0.1</version> + <scope>test</scope> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/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 new file mode 100644 index 0000000..858a55d --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java @@ -0,0 +1,206 @@ +/* + * 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.audit; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.ThreadContext; +import org.apache.logging.log4j.audit.catalog.CatalogManager; +import org.apache.logging.log4j.audit.exception.AuditException; +import org.apache.logging.log4j.catalog.api.Attribute; +import org.apache.logging.log4j.catalog.api.Constraint; +import org.apache.logging.log4j.catalog.api.Event; +import org.apache.logging.log4j.catalog.api.EventAttribute; +import org.apache.logging.log4j.catalog.api.plugins.ConstraintPlugins; +import org.apache.logging.log4j.message.StructuredDataMessage; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * + */ +public abstract class AbstractEventLogger { + + private static final Logger logger = LogManager.getLogger(AbstractEventLogger.class); + + private static final int DEFAULT_MAX_LENGTH = 32; + + private static ConstraintPlugins constraintPlugins = ConstraintPlugins.getInstance(); + + public CatalogManager catalogManager; + + private static final AuditExceptionHandler DEFAULT_EXCEPTION_HANDLER = (message, ex) -> { + throw new AuditException("Error logging event " + message.getId().getName(), ex); + }; + + private static final AuditExceptionHandler NOOP_EXCEPTION_HANDLER = (message, ex) -> { + }; + + private AuditExceptionHandler defaultAuditExceptionHandler = DEFAULT_EXCEPTION_HANDLER; + + private final int maxLength; + + protected AbstractEventLogger() { + maxLength = DEFAULT_MAX_LENGTH; + } + + protected AbstractEventLogger(int maxLength) { + this.maxLength = maxLength; + } + + public void setCatalogManager(CatalogManager catalogManager) { + this.catalogManager = catalogManager; + } + + public List<String> getAttributeNames(String eventId) { + return catalogManager.getAttributeNames(eventId); + } + + public void setDefaultAuditExceptionHandler(AuditExceptionHandler auditExceptionHandler) { + defaultAuditExceptionHandler = auditExceptionHandler == null ? NOOP_EXCEPTION_HANDLER : auditExceptionHandler; + } + + public void logEvent(String eventName, Map<String, String> attributes) { + Event event = catalogManager.getEvent(eventName); + if (event == null) { + throw new AuditException("Unable to locate definition of audit event " + eventName); + } + logEvent(eventName, attributes, event, defaultAuditExceptionHandler); + } + + public void logEvent(String eventName, Map<String, String> attributes, AuditExceptionHandler exceptionHandler) { + Event event = catalogManager.getEvent(eventName); + + if (event == null) { + throw new AuditException("Unable to locate definition of audit event " + eventName); + } + logEvent(eventName, attributes, event, exceptionHandler); + } + + protected abstract void logEvent(StructuredDataMessage message); + + private void logEvent(String eventName, Map<String, String> attributes, Event event, + AuditExceptionHandler exceptionHandler) { + AuditMessage msg = new AuditMessage(eventName, maxLength); + + StringBuilder missingAttributes = new StringBuilder(); + StringBuilder errors = new StringBuilder(); + + for (EventAttribute eventAttribute : event.getAttributes()) { + Attribute attr = catalogManager.getAttribute(eventAttribute.getName()); + if (!attr.isRequestContext() && (attr.isRequired() || eventAttribute.isRequired())) { + String name = attr.getName(); + if (!attributes.containsKey(name)) { + if (missingAttributes.length() > 0) { + missingAttributes.append(", "); + } + missingAttributes.append(name); + } else { + if (attr.getConstraints() != null && attr.getConstraints().size() > 0) { + Constraint[] constraints = attr.getConstraints().toArray(new Constraint[attr.getConstraints().size()]); + validateConstraints(false, constraints, name, attributes.get(name), errors); + } + } + } + } + Map<String, Attribute> attributeMap = catalogManager.getAttributes(eventName); + for (String name : attributes.keySet()) { + if (!attributeMap.containsKey(name) && !name.equals("completionStatus")) { + if (errors.length() > 0) { + errors.append("\n"); + } + errors.append("Attribute ").append(name).append(" is not defined for ").append(eventName); + } + } + if (missingAttributes.length() > 0) { + if (errors.length() > 0) { + errors.append("\n"); + } + errors.append("Event ").append(eventName).append(" is missing required attribute(s) ").append(missingAttributes.toString()); + } + if (errors.length() > 0) { + throw new AuditException(errors.toString()); + } + List<String> attributeNames = catalogManager.getAttributeNames(eventName); + StringBuilder buf = new StringBuilder(); + for (String attribute : attributes.keySet()) { + if (!attributeNames.contains(attribute)) { + if (buf.length() > 0) { + buf.append(", "); + } + buf.append(attribute); + } + } + if (buf.length() > 0) { + throw new AuditException("Event " + eventName + " contains invalid attribute(s) " + buf.toString()); + } + + List<String> reqCtxAttrs = catalogManager.getRequiredContextAttributes(eventName); + + if (reqCtxAttrs != null) { + StringBuilder sb = new StringBuilder(); + for (String attr : reqCtxAttrs) { + if (!ThreadContext.containsKey(attr)) { + if (sb.length() > 0) { + sb.append(", "); + } + sb.append(attr); + } + } + if (sb.length() > 0) { + throw new IllegalStateException("Event " + msg.getId().getName() + + " is missing required RequestContext values for " + sb.toString()); + } + } + Map<String, Attribute> reqCtxAttributes = catalogManager.getRequestContextAttributes(); + for (Map.Entry<String, String> entry : ThreadContext.getImmutableContext().entrySet()) { + Attribute attribute = reqCtxAttributes.get(entry.getKey()); + if (attribute == null) { + continue; + } + Set<Constraint> constraintList = attribute.getConstraints(); + if (constraintList != null && constraintList.size() > 0) { + Constraint[] constraints = + attribute.getConstraints().toArray(new Constraint[attribute.getConstraints().size()]); + validateConstraints(true, constraints, entry.getKey(), ThreadContext.get(entry.getKey()), errors); + } + } + if (errors.length() > 0) { + throw new AuditException("Event " + eventName + " has incorrect data in the Thread Context: " + errors.toString()); + } + msg.putAll(attributes); + try { + logEvent(msg); + } catch (Throwable ex) { + if (exceptionHandler == null) { + defaultAuditExceptionHandler.handleException(msg, ex); + } else { + exceptionHandler.handleException(msg, ex); + } + } + } + + private static void validateConstraints(boolean isRequestContext, Constraint[] constraints, String name, + String value, StringBuilder errors) { + for (Constraint constraint : constraints) { + constraintPlugins.validateConstraint(isRequestContext, constraint.getConstraintType().getName(), name, value, + constraint.getValue(), errors); + } + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java new file mode 100644 index 0000000..5c1381f --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/ActivityLogger.java @@ -0,0 +1,49 @@ +/* + * 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.audit; + +import org.apache.logging.log4j.EventLogger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.message.StructuredDataMessage; +import org.apache.logging.log4j.spi.ExtendedLogger; + +/** + * + */ +public class ActivityLogger extends AbstractEventLogger { + private static final String NAME = "ActivityLogger"; + + private static final String FQCN = ActivityLogger.class.getName(); + private static Marker EVENT_MARKER = MarkerManager.getMarker("Activity").addParents(EventLogger.EVENT_MARKER); + private static final ExtendedLogger LOGGER = LogManager.getContext(false).getLogger(NAME); + + public ActivityLogger() { + super(); + } + + public ActivityLogger(int maxLength) { + super(maxLength); + } + + @Override + protected void logEvent(StructuredDataMessage message) { + LOGGER.logIfEnabled(FQCN, Level.OFF, EVENT_MARKER, message, null); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java new file mode 100644 index 0000000..cad2ea0 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditEvent.java @@ -0,0 +1,41 @@ +/* + * 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.audit; + +/** + * Interface that is extended by generated classes. + */ +public interface AuditEvent { + + /** + * Log the event. + */ + void logEvent(); + + /** + * Set the exception handler to use. The default exception handler will throw an AuditException wrapping the + * exception that occurred. If null is passed in then the exception will be ignored. + * @param exceptionHandler The exception handler. + */ + void setAuditExceptionHandler(AuditExceptionHandler exceptionHandler); + + /** + * Added to the event after the operation has completed. Identifies whether it was successful or not. + * @param status The completion status. + */ + void setCompletionStatus(String status); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java new file mode 100644 index 0000000..adf6376 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditExceptionHandler.java @@ -0,0 +1,33 @@ +/* + * 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.audit; + +import org.apache.logging.log4j.message.StructuredDataMessage; + +/** + * Handles any exceptions that may occur while logging the audit event. + */ +public interface AuditExceptionHandler { + + /** + * Handles Exceptions that occur while audit logging. If a RuntimeException is thrown it will percolate + * back to the application. + * @param message The message being loggeed. + * @param ex The Throwable. + */ + void handleException(StructuredDataMessage message, Throwable ex); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java new file mode 100644 index 0000000..d521399 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditLogger.java @@ -0,0 +1,50 @@ +/* + * 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.audit; + +import org.apache.logging.log4j.EventLogger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.message.StructuredDataMessage; +import org.apache.logging.log4j.spi.ExtendedLogger; + +/** + * + */ +public class AuditLogger extends AbstractEventLogger { + + private static final String NAME = "AuditLogger"; + + private static final String FQCN = AuditLogger.class.getName(); + private static Marker EVENT_MARKER = MarkerManager.getMarker("Audit").addParents(EventLogger.EVENT_MARKER); + private static final ExtendedLogger LOGGER = LogManager.getContext(false).getLogger(NAME); + + public AuditLogger() { + super(); + } + + public AuditLogger(int maxLength) { + super(maxLength); + } + + @Override + protected void logEvent(StructuredDataMessage message) { + LOGGER.logIfEnabled(FQCN, Level.OFF, EVENT_MARKER, message, null); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java new file mode 100644 index 0000000..35b15a5 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AuditMessage.java @@ -0,0 +1,58 @@ +/* + * 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.audit; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.logging.log4j.message.StructuredDataId; +import org.apache.logging.log4j.message.StructuredDataMessage; + +/** + * + */ +public class AuditMessage extends StructuredDataMessage { + + private static final int MAX_LENGTH = 32; + + private Map<String, StructuredDataMessage> extraContent = new HashMap<>(); + + public AuditMessage(String eventName) { + this(eventName, MAX_LENGTH); + } + + public AuditMessage(String eventName, int maxLength) { + // Use this with Log4j 2.9 + // super(new AuditId(eventName, MAX_LENGTH), null, "Audit", maxLength); + super(new AuditId(eventName, maxLength), null, "Audit"); + } + + public void addContent(String name, StructuredDataMessage message) { + extraContent.put(name, message); + } + + private static class AuditId extends StructuredDataId { + + AuditId(String eventName, int maxLength) { + // Use this with Log4j 2.9 + // super(eventName, maxLength); + super(eventName, null, null); + } + + } + +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java new file mode 100644 index 0000000..ef2cdf1 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java @@ -0,0 +1,385 @@ +/* + * 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.audit; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.EventLogger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.ThreadContext; +import org.apache.logging.log4j.audit.annotation.Constraint; +import org.apache.logging.log4j.audit.annotation.Constraints; +import org.apache.logging.log4j.audit.annotation.MaxLength; +import org.apache.logging.log4j.audit.annotation.RequestContext; +import org.apache.logging.log4j.audit.annotation.RequestContextConstraints; +import org.apache.logging.log4j.audit.annotation.Required; +import org.apache.logging.log4j.audit.exception.AuditException; +import org.apache.logging.log4j.audit.util.NamingUtils; +import org.apache.logging.log4j.catalog.api.exception.ConstraintValidationException; +import org.apache.logging.log4j.catalog.api.plugins.ConstraintPlugins; +import org.apache.logging.log4j.message.StructuredDataMessage; +import org.apache.logging.log4j.spi.ExtendedLogger; + +import static org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline; + +/** + * + */ +public class LogEventFactory { + + private static final Logger logger = LogManager.getLogger(LogEventFactory.class); + private static final String NAME = "AuditLogger"; + private static final String FQCN = LogEventFactory.class.getName(); + private static Marker EVENT_MARKER = MarkerManager.getMarker("Audit").addParents(EventLogger.EVENT_MARKER); + private static final ExtendedLogger LOGGER = LogManager.getContext(false).getLogger(NAME); + private static final int DEFAULT_MAX_LENGTH = 32; + + private static final AuditExceptionHandler DEFAULT_HANDLER = (message, ex) -> { + throw new AuditException("Error logging event " + message.getId().getName(), ex); + }; + + private static final AuditExceptionHandler NOOP_EXCEPTION_HANDLER = (message, ex) -> { + }; + + private static AuditExceptionHandler defaultExceptionHandler = DEFAULT_HANDLER; + + private static ConcurrentMap<Class<?>, List<Property>> classMap = new ConcurrentHashMap<>(); + + private static ConstraintPlugins constraintPlugins = ConstraintPlugins.getInstance(); + + public static void setDefaultHandler(AuditExceptionHandler exceptionHandler) { + defaultExceptionHandler = (exceptionHandler == null) ? NOOP_EXCEPTION_HANDLER : exceptionHandler; + } + + @SuppressWarnings("unchecked") + public static <T> T getEvent(Class<T> intrface) { + + Class<?>[] interfaces = new Class<?>[] { intrface }; + + String eventId = NamingUtils.lowerFirst(intrface.getSimpleName()); + int msgLength = intrface.getAnnotation(MaxLength.class).value(); + AuditMessage msg = new AuditMessage(eventId, msgLength); + AuditEvent audit = (AuditEvent) Proxy.newProxyInstance(intrface + .getClassLoader(), interfaces, new AuditProxy(msg, intrface)); + + return (T) audit; + } + + public static void logEvent(Class<?> intrface, Map<String, String> properties) { + logEvent(intrface, properties, DEFAULT_HANDLER); + } + + public static void logEvent(Class<?> intrface, Map<String, String> properties, AuditExceptionHandler handler) { + StringBuilder errors = new StringBuilder(); + validateContextConstraints(intrface, errors); + + String eventId = NamingUtils.lowerFirst(intrface.getSimpleName()); + int maxLength = intrface.getAnnotation(MaxLength.class).value(); + AuditMessage msg = new AuditMessage(eventId, maxLength); + List<Property> props = getProperties(intrface); + Map<String, Property> propertyMap = new HashMap<>(); + + for (Property property : props ) { + propertyMap.put(property.name, property); + if (property.isRequired && !properties.containsKey(property.name)) { + if (errors.length() > 0) { + errors.append("\n"); + } + errors.append("Required attribute ").append(property.name).append(" is missing from ").append(eventId); + } + if (properties.containsKey(property.name)) { + validateConstraints(false, property.constraints, property.name, properties, errors); + } + } + + for (Map.Entry<String, String> entry : properties.entrySet()) { + if (!propertyMap.containsKey(entry.getKey())) { + if (errors.length() > 0) { + errors.append("Attribute ").append(entry.getKey()).append(" is not defined for ").append(eventId); + } + } + } + + if (errors.length() > 0) { + throw new ConstraintValidationException(errors.toString()); + } + for (Map.Entry<String, String> entry : properties.entrySet()) { + msg.put(entry.getKey(), entry.getValue()); + } + logEvent(msg, handler); + } + + public static void logEvent(AuditMessage msg, AuditExceptionHandler handler) { + try { + LOGGER.logIfEnabled(FQCN, Level.OFF, EVENT_MARKER, msg, null); + } catch (Throwable ex) { + if (handler == null) { + handler = defaultExceptionHandler; + } + handler.handleException(msg, ex); + } + } + + public static List<String> getPropertyNames(String className) { + Class<?> intrface = getClass(className); + List<String> names; + if (intrface != null) { + List<Property> props = getProperties(intrface); + names = new ArrayList<>(props.size()); + for (Property prop : props) { + names.add(prop.name); + } + } else { + names = new ArrayList<>(); + } + return names; + } + + private static List<Property> getProperties(Class<?> intrface) { + List<Property> props = classMap.get(intrface); + if (props != null) { + return props; + } + props = new ArrayList<>(); + Method[] methods = intrface.getMethods(); + boolean isCompletionStatus = false; + for (Method method : methods) { + if (method.getName().startsWith("set") && !method.getName().equals("setAuditExceptionHandler")) { + if (method.getName().equals("setCompletionStatus")) { + isCompletionStatus = true; + } + String name = NamingUtils.lowerFirst(NamingUtils.getMethodShortName(method.getName())); + Annotation[] annotations = method.getDeclaredAnnotations(); + List<Constraint> constraints = new ArrayList<>(); + boolean isRequired = false; + for (Annotation annotation : annotations) { + if (annotation instanceof Constraint) { + constraints.add((Constraint) annotation); + } + if (annotation instanceof Required) { + isRequired = true; + } + } + props.add(new Property(name, isRequired, constraints)); + } + } + if (!isCompletionStatus) { + props.add(new Property("completionStatus", false, new ArrayList<>())); + } + + classMap.putIfAbsent(intrface, props); + return classMap.get(intrface); + } + + private static Class<?> getClass(String className) { + try { + Class<?> intrface = Class.forName(className); + if (AuditEvent.class.isAssignableFrom(intrface)) { + return intrface; + } + logger.error(className + " is not an AuditEvent"); + } catch (ClassNotFoundException cnfe) { + logger.error("Unable to locate class {}", className); + } + return null; + } + + private static class AuditProxy implements InvocationHandler { + + private final AuditMessage msg; + private final Class<?> intrface; + private AuditExceptionHandler auditExceptionHandler = DEFAULT_HANDLER; + + AuditProxy(AuditMessage msg, Class<?> intrface) { + this.msg = msg; + this.intrface = intrface; + } + + public AuditMessage getMessage() { + return msg; + } + + @Override + @SuppressWarnings("unchecked") + public Object invoke(Object o, Method method, Object[] objects) + throws Throwable { + if (method.getName().equals("logEvent")) { + + StringBuilder errors = new StringBuilder(); + validateContextConstraints(intrface, errors); + + StringBuilder missing = new StringBuilder(); + Method[] methods = intrface.getMethods(); + + for (Method _method : methods) { + String name = NamingUtils.lowerFirst(NamingUtils.getMethodShortName(_method.getName())); + + Annotation[] annotations = _method.getDeclaredAnnotations(); + for (Annotation annotation : annotations) { + if (annotation instanceof Required && msg.get(name) == null) { + if (missing.length() > 0) { + missing.append(", "); + } + missing.append(name); + } + } + } + if (errors.length() > 0) { + if (missing.length() > 0) { + errors.append("\n"); + errors.append("Required attributes are missing: "); + errors.append(missing.toString()); + } + } else if (missing.length() > 0) { + errors.append("Required attributes are missing: "); + errors = missing; + } + + if (errors.length() > 0) { + throw new ConstraintValidationException("Event " + msg.getId().getName() + + " has errors :\n" + errors.toString()); + } + + logEvent(msg, auditExceptionHandler); + } + if (method.getName().equals("setCompletionStatus")) { + String name = NamingUtils.lowerFirst(NamingUtils.getMethodShortName(method.getName())); + if (objects == null || objects[0] == null) { + throw new IllegalArgumentException("Missing completion status"); + } + msg.put(name, objects[0].toString()); + } + if (method.getName().equals("setAuditExceptionHandler")) { + if (objects == null || objects[0] == null) { + auditExceptionHandler = NOOP_EXCEPTION_HANDLER; + } else if (objects[0] instanceof AuditExceptionHandler) { + auditExceptionHandler = (AuditExceptionHandler) objects[0]; + } else { + throw new IllegalArgumentException(objects[0] + " is not an " + AuditExceptionHandler.class.getName()); + } + } + if (method.getName().startsWith("set")) { + String name = NamingUtils.lowerFirst(NamingUtils.getMethodShortName(method.getName())); + if (objects == null || objects[0] == null) { + throw new IllegalArgumentException("No value to be set for " + name); + } + + Annotation[] annotations = method.getDeclaredAnnotations(); + Class<?> returnType = method.getReturnType(); + StringBuilder errors = new StringBuilder(); + for (Annotation annotation : annotations) { + + if (annotation instanceof Constraints) { + Constraints constraints = (Constraints) annotation; + validateConstraints(false, constraints.value(), name, objects[0].toString(), + errors); + } else if (annotation instanceof Constraint) { + Constraint constraint = (Constraint) annotation; + constraintPlugins.validateConstraint(false, constraint.constraintType(), + name, objects[0].toString(), constraint.constraintValue(), errors); + } + } + if (errors.length() > 0) { + throw new ConstraintValidationException(errors.toString()); + } + String result; + if (objects[0] instanceof List) { + result = StringUtils.join(objects, ", "); + } else if (objects[0] instanceof Map) { + StructuredDataMessage extra = new StructuredDataMessage(name, null, null); + extra.putAll((Map)objects[0]); + msg.addContent(name, extra); + return null; + } else { + result = objects[0].toString(); + } + + msg.put(name, result); + } + + return null; + } + } + + private static void validateConstraints(boolean isRequestContext, Constraint[] constraints, String name, + Map<String, String> properties, StringBuilder errors) { + String value = isRequestContext ? ThreadContext.get(name) : properties.get(name); + validateConstraints(isRequestContext, constraints, name, value, errors); + } + + private static void validateConstraints(boolean isRequestContext, Constraint[] constraints, String name, + String value, StringBuilder errors) { + for (Constraint constraint : constraints) { + constraintPlugins.validateConstraint(isRequestContext, constraint.constraintType(), name, value, + constraint.constraintValue(), errors); + } + } + + private static void validateContextConstraints(Class<?> intrface, StringBuilder buffer) { + RequestContextConstraints reqCtxConstraints = intrface.getAnnotation(RequestContextConstraints.class); + if (reqCtxConstraints != null) { + for (RequestContext ctx : reqCtxConstraints.value()) { + validateContextConstraint(ctx, buffer); + } + } else { + RequestContext ctx = intrface.getAnnotation(RequestContext.class); + validateContextConstraint(ctx, buffer); + } + } + + private static void validateContextConstraint(RequestContext constraint, StringBuilder errors) { + String value = ThreadContext.get(constraint.key()); + if (value != null) { + validateConstraints(true, constraint.constraints(), constraint.key(), value, errors); + } else if (constraint.required()) { + appendNewline(errors); + errors.append("ThreadContext does not contain required key ").append(constraint.key()); + } + } + + private static boolean isBlank(String value) { + return value != null && value.length() > 0; + } + + private static class Property { + private final String name; + private final boolean isRequired; + private final Constraint[] constraints; + + public Property(String name, boolean isRequired, List<Constraint> constraints) { + this.name = name; + this.constraints = constraints.toArray(new Constraint[constraints.size()]); + this.isRequired = isRequired; + } + } + +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java new file mode 100644 index 0000000..d2f66ba --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraint.java @@ -0,0 +1,33 @@ +/* + * 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.audit.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(Constraints.class) +public @interface Constraint { + + String constraintType(); + + String constraintValue(); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java new file mode 100644 index 0000000..4190fe0 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Constraints.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.log4j.audit.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Container for Constraints. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Constraints { + Constraint[] value(); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java ---------------------------------------------------------------------- diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java new file mode 100644 index 0000000..fdf1b53 --- /dev/null +++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/MaxLength.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.log4j.audit.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Recoreds the maximum length of dynamic attribute names. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MaxLength { + int value(); +}
