You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by jk...@apache.org on 2022/05/10 21:00:59 UTC
[unomi] 01/01: UNOMI-568: refacto json-schema implementation
This is an automated email from the ASF dual-hosted git repository.
jkevan pushed a commit to branch refacto-json-schema
in repository https://gitbox.apache.org/repos/asf/unomi.git
commit 723d8edb527d9b19e7d4bbb2946d365bd0cdc3f8
Author: Kevan <ke...@jahia.com>
AuthorDate: Tue May 10 22:50:42 2022 +0200
UNOMI-568: refacto json-schema implementation
---
.../unomi/api/schema/JSONSchemaExtension.java | 83 -----
extensions/{ => json-schema}/pom.xml | 22 +-
extensions/json-schema/rest/pom.xml | 89 ++++++
.../unomi/schema/rest}/JsonSchemaEndPoint.java | 15 +-
extensions/json-schema/services/pom.xml | 154 ++++++++++
.../apache/unomi/schema/api/JsonSchemaWrapper.java | 14 +-
.../apache/unomi/schema/api}/SchemaService.java | 81 +----
.../unomi/schema/impl/SchemaServiceImpl.java | 241 +++++++++++++++
.../unomi/schema/listener/JsonSchemaListener.java | 137 +++++++++
.../resources/META-INF/cxs/schemas/condition.json | 0
.../META-INF/cxs/schemas/conditiontype.json | 0
.../resources/META-INF/cxs/schemas/consent.json | 0
.../META-INF/cxs/schemas/consentType.json | 0
.../resources/META-INF/cxs/schemas/customitem.json | 0
.../META-INF/cxs/schemas/customitems/page.json | 0
.../META-INF/cxs/schemas/customitems/site.json | 0
.../main/resources/META-INF/cxs/schemas/event.json | 0
.../cxs/schemas/events/anonymizeProfile.json | 0
.../cxs/schemas/events/articleCompleted.json | 0
.../META-INF/cxs/schemas/events/form.json | 0
.../META-INF/cxs/schemas/events/goal.json | 0
.../META-INF/cxs/schemas/events/identify.json | 0
.../cxs/schemas/events/incrementInterest.json | 0
.../META-INF/cxs/schemas/events/login.json | 0
.../META-INF/cxs/schemas/events/modifyConsent.json | 0
.../cxs/schemas/events/profileDeleted.json | 0
.../cxs/schemas/events/profileUpdated.json | 0
.../META-INF/cxs/schemas/events/ruleFired.json | 0
.../META-INF/cxs/schemas/events/search.json | 0
.../cxs/schemas/events/sessionCreated.json | 0
.../cxs/schemas/events/sessionReassigned.json | 0
.../cxs/schemas/events/updateProperties.json | 0
.../META-INF/cxs/schemas/events/view.json | 0
.../main/resources/META-INF/cxs/schemas/goal.json | 0
.../main/resources/META-INF/cxs/schemas/item.json | 0
.../resources/META-INF/cxs/schemas/metadata.json | 0
.../META-INF/cxs/schemas/metadataitem.json | 0
.../resources/META-INF/cxs/schemas/parameter.json | 0
.../cxs/schemas/personalization/filter.json | 0
.../personalization/personalizationrequest.json | 0
.../personalization/personalizedcontent.json | 0
.../cxs/schemas/personalization/target.json | 0
.../resources/META-INF/cxs/schemas/profile.json | 0
.../resources/META-INF/cxs/schemas/session.json | 0
.../META-INF/cxs/schemas/timestampeditem.json | 21 +-
.../META-INF/cxs/schemas/values/boolean.json | 0
.../META-INF/cxs/schemas/values/date.json | 0
.../META-INF/cxs/schemas/values/email.json | 0
.../META-INF/cxs/schemas/values/integer.json | 0
.../META-INF/cxs/schemas/values/long.json | 0
.../resources/META-INF/cxs/schemas/values/set.json | 0
.../META-INF/cxs/schemas/values/string.json | 0
.../resources/OSGI-INF/blueprint/blueprint.xml | 54 ++++
.../src/main/resources/org.apache.unomi.schema.cfg | 19 ++
extensions/pom.xml | 1 +
graphql/cxs-impl/pom.xml | 6 +
.../graphql/schema/GraphQLSchemaProvider.java | 33 +-
.../unomi/graphql/schema/GraphQLSchemaUpdater.java | 2 +-
.../unomi/graphql}/schema/json/JSONArrayType.java | 2 +-
.../graphql}/schema/json/JSONBooleanType.java | 2 +-
.../unomi/graphql}/schema/json/JSONEnumType.java | 2 +-
.../graphql}/schema/json/JSONIntegerType.java | 2 +-
.../unomi/graphql}/schema/json/JSONNullType.java | 2 +-
.../unomi/graphql}/schema/json/JSONNumberType.java | 2 +-
.../unomi/graphql}/schema/json/JSONObjectType.java | 2 +-
.../unomi/graphql}/schema/json/JSONSchema.java | 2 +-
.../unomi/graphql}/schema/json/JSONStringType.java | 2 +-
.../unomi/graphql}/schema/json/JSONType.java | 2 +-
.../graphql}/schema/json/JSONTypeFactory.java | 10 +-
.../types/resolvers/CDPEventInterfaceResolver.java | 13 +-
.../java/org/apache/unomi/itests/JSONSchemaIT.java | 60 +---
.../extension/extension-test-event-example.json | 26 --
kar/pom.xml | 5 +
kar/src/main/feature/feature.xml | 3 +
.../resources/OSGI-INF/blueprint/blueprint.xml | 2 +
rest/pom.xml | 6 +
.../deserializers/ContextRequestDeserializer.java | 6 +-
.../EventsCollectorRequestDeserializer.java | 6 +-
.../unomi/rest/endpoints/ContextJsonEndpoint.java | 8 +-
.../endpoints/JsonSchemaExtensionEndPoint.java | 109 -------
.../org/apache/unomi/rest/server/RestServer.java | 2 +-
.../rest/service/impl/RestServiceUtilsImpl.java | 9 +-
.../META-INF/cxs/schemas/contextrequest.json | 0
.../META-INF/cxs/schemas/contextrequestparams.json | 0
.../resources/META-INF/cxs/schemas/cookie.json | 0
.../cxs/schemas/eventscollectorrequest.json | 0
services/pom.xml | 11 -
.../services/impl/events/EventServiceImpl.java | 5 -
.../services/impl/schemas/SchemaServiceImpl.java | 339 ---------------------
.../impl/schemas/UnomiPropertyTypeKeyword.java | 126 --------
.../services/listener/JsonSchemaListener.java | 217 -------------
.../resources/OSGI-INF/blueprint/blueprint.xml | 24 --
.../main/resources/org.apache.unomi.services.cfg | 3 -
.../resources/OSGI-INF/blueprint/blueprint.xml | 2 +
94 files changed, 834 insertions(+), 1150 deletions(-)
diff --git a/api/src/main/java/org/apache/unomi/api/schema/JSONSchemaExtension.java b/api/src/main/java/org/apache/unomi/api/schema/JSONSchemaExtension.java
deleted file mode 100644
index 652102dfa..000000000
--- a/api/src/main/java/org/apache/unomi/api/schema/JSONSchemaExtension.java
+++ /dev/null
@@ -1,83 +0,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.
- */
-package org.apache.unomi.api.schema;
-
-import org.apache.unomi.api.Metadata;
-import org.apache.unomi.api.MetadataItem;
-
-/**
- * Object which represents a JSON schema extensions stored in the persistence service
- */
-public class JSONSchemaExtension extends MetadataItem {
- public static final String ITEM_TYPE = "jsonSchemaExtension";
-
- private String id;
- private String extension;
- private double priority;
- private String schemaId;
-
- public JSONSchemaExtension() {
- }
-
- /**
- * Instantiates a new JSON schema with an id and a schema extension as string
- *
- * @param id id of the extension
- * @param schemaId id of the schema
- * @param extension as string
- * @param priority priority to process the extension
- */
- public JSONSchemaExtension(String id, String schemaId, String extension, float priority) {
- super(new Metadata(id));
- this.id = id;
- this.extension = extension;
- this.priority = priority;
- this.schemaId = schemaId;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getExtension() {
- return extension;
- }
-
- public void setExtension(String extension) {
- this.extension = extension;
- }
-
- public double getPriority() {
- return priority;
- }
-
- public void setPriority(double priority) {
- this.priority = priority;
- }
-
- public String getSchemaId() {
- return schemaId;
- }
-
- public void setSchemaId(String schemaId) {
- this.schemaId = schemaId;
- }
-}
diff --git a/extensions/pom.xml b/extensions/json-schema/pom.xml
similarity index 67%
copy from extensions/pom.xml
copy to extensions/json-schema/pom.xml
index 70105e5f5..e869e05d0 100644
--- a/extensions/pom.xml
+++ b/extensions/json-schema/pom.xml
@@ -13,33 +13,25 @@
~ 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
+ ~ 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
-
<parent>
<groupId>org.apache.unomi</groupId>
- <artifactId>unomi-root</artifactId>
+ <artifactId>unomi-extensions</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
- <artifactId>unomi-extensions</artifactId>
- <name>Apache Unomi :: Extensions</name>
- <description>Apache Unomi Context Server extensions</description>
+ <artifactId>unomi-json-schema-root</artifactId>
+ <name>Apache Unomi :: Extensions :: JSON Schema</name>
+ <description>TODO</description>
<packaging>pom</packaging>
<modules>
- <module>lists-extension</module>
- <module>privacy-extension</module>
- <module>geonames</module>
- <module>router</module>
- <module>salesforce-connector</module>
- <module>unomi-mailchimp</module>
- <module>weather-update</module>
- <module>web-tracker</module>
- <module>groovy-actions</module>
+ <module>services</module>
+ <module>rest</module>
</modules>
</project>
diff --git a/extensions/json-schema/rest/pom.xml b/extensions/json-schema/rest/pom.xml
new file mode 100644
index 000000000..e69f1a8bf
--- /dev/null
+++ b/extensions/json-schema/rest/pom.xml
@@ -0,0 +1,89 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-json-schema-root</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>unomi-json-schema-rest</artifactId>
+ <name>Apache Unomi :: Extensions :: JSON Schema :: REST API</name>
+ <description>TODO</description>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-json-schema-services</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-rs-security-cors</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.cmpn</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/JsonSchemaEndPoint.java b/extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java
similarity index 92%
rename from rest/src/main/java/org/apache/unomi/rest/endpoints/JsonSchemaEndPoint.java
rename to extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java
index dfc8900eb..c7115e791 100644
--- a/rest/src/main/java/org/apache/unomi/rest/endpoints/JsonSchemaEndPoint.java
+++ b/extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-package org.apache.unomi.rest.endpoints;
+package org.apache.unomi.schema.rest;
import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
import org.apache.unomi.api.Metadata;
-import org.apache.unomi.api.services.SchemaService;
+import org.apache.unomi.schema.api.SchemaService;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
@@ -27,15 +27,7 @@ import org.slf4j.LoggerFactory;
import javax.jws.WebMethod;
import javax.jws.WebService;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
+import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Base64;
@@ -92,6 +84,7 @@ public class JsonSchemaEndPoint {
@Produces(MediaType.APPLICATION_JSON)
public Response save(String jsonSchema) {
schemaService.saveSchema(jsonSchema);
+ // TODO we should return error in case save failed (for example saving a schema with an ID of an already existing predefined schema is forbidden)
return Response.ok().build();
}
diff --git a/extensions/json-schema/services/pom.xml b/extensions/json-schema/services/pom.xml
new file mode 100644
index 000000000..8a5cee47e
--- /dev/null
+++ b/extensions/json-schema/services/pom.xml
@@ -0,0 +1,154 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-json-schema-root</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>unomi-json-schema-services</artifactId>
+ <name>Apache Unomi :: Extensions :: JSON Schema :: Service</name>
+ <description>TODO</description>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <version.schema>1.0.69</version.schema>
+ <version.schema.jackson>2.12.1</version.schema.jackson>
+ <version.schema.itu>1.5.1</version.schema.itu>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.cmpn</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-persistence-spi</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+
+ <!-- dependencies required for json-schema framework -->
+ <dependency>
+ <groupId>com.networknt</groupId>
+ <artifactId>json-schema-validator</artifactId>
+ <version>${version.schema}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.ethlo.time</groupId>
+ <artifactId>itu</artifactId>
+ <version>${version.schema.itu}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${version.schema.jackson}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${version.schema.jackson}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${version.schema.jackson}</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
+ <Unomi-Source-Folders>${project.basedir}</Unomi-Source-Folders>
+ <Export-Package>
+ org.apache.unomi.schema.api
+ </Export-Package>
+ <Import-Package>
+ sun.misc;resolution:=optional,
+ org.jcodings;resolution:=optional,
+ org.jcodings.specific;resolution:=optional,
+ org.joni;resolution:=optional,
+ org.joni.exception;resolution:=optional,
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>
+ src/main/resources/org.apache.unomi.schema.cfg
+ </file>
+ <type>cfg</type>
+ <classifier>schemacfg</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/api/src/main/java/org/apache/unomi/api/schema/UnomiJSONSchema.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/JsonSchemaWrapper.java
similarity index 86%
rename from api/src/main/java/org/apache/unomi/api/schema/UnomiJSONSchema.java
rename to extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/JsonSchemaWrapper.java
index 3ae507709..444a306d8 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/UnomiJSONSchema.java
+++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/JsonSchemaWrapper.java
@@ -14,22 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema;
+
+package org.apache.unomi.schema.api;
import org.apache.unomi.api.Metadata;
import org.apache.unomi.api.MetadataItem;
-/**
- * Object which represents a JSON schema stored in the persistence service
- */
-public class UnomiJSONSchema extends MetadataItem {
+public class JsonSchemaWrapper extends MetadataItem {
public static final String ITEM_TYPE = "jsonSchema";
private String id;
private String schema;
private String target;
- public UnomiJSONSchema(){}
+ public JsonSchemaWrapper(){}
/**
* Instantiates a new JSON schema with an id and a schema as string
@@ -38,7 +36,7 @@ public class UnomiJSONSchema extends MetadataItem {
* @param schema as string
* @param target of the schema
*/
- public UnomiJSONSchema(String id, String schema, String target) {
+ public JsonSchemaWrapper(String id, String schema, String target) {
super(new Metadata(id));
this.id = id;
this.schema = schema;
@@ -68,4 +66,4 @@ public class UnomiJSONSchema extends MetadataItem {
public void setTarget(String target) {
this.target = target;
}
-}
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/apache/unomi/api/services/SchemaService.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java
similarity index 54%
rename from api/src/main/java/org/apache/unomi/api/services/SchemaService.java
rename to extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java
index 7d6e65480..2692891a0 100644
--- a/api/src/main/java/org/apache/unomi/api/services/SchemaService.java
+++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java
@@ -15,12 +15,10 @@
* limitations under the License.
*/
-package org.apache.unomi.api.services;
+package org.apache.unomi.schema.api;
-import com.fasterxml.jackson.databind.JsonNode;
import org.apache.unomi.api.Metadata;
import org.apache.unomi.api.PartialList;
-import org.apache.unomi.api.schema.json.JSONSchema;
import java.io.IOException;
import java.io.InputStream;
@@ -48,11 +46,11 @@ public interface SchemaService {
/**
* Verify if a jsonNode is valid against a schema
*
- * @param jsonNode to validate
+ * @param data to validate
* @param schemaId id of the schema used for the validation
* @return true is the object is valid
*/
- boolean isValid(JsonNode jsonNode, String schemaId);
+ boolean isValid(String data, String schemaId);
/**
* Get a schema matching by a schema id
@@ -60,15 +58,15 @@ public interface SchemaService {
* @param schemaId Id of the schema
* @return A JSON schema
*/
- JSONSchema getSchema(String schemaId);
+ JsonSchemaWrapper getSchema(String schemaId);
/**
- * Get a list a {@link org.apache.unomi.api.schema.json.JSONSchema}
+ * Get a list a {@link JsonSchemaWrapper}
*
* @param target to filter the schemas
* @return a list of JSONSchema
*/
- List<JSONSchema> getSchemasByTarget(String target);
+ List<JsonSchemaWrapper> getSchemasByTarget(String target);
/**
* Save a new schema or update a schema
@@ -77,20 +75,6 @@ public interface SchemaService {
*/
void saveSchema(String schema);
- /**
- * Save a new schema or update a schema
- *
- * @param schemaStream inputStream of the schema
- */
- void saveSchema(InputStream schemaStream) throws IOException;
-
- /**
- * Load a predefined schema into memory
- *
- * @param schemaStream inputStream of the schema
- */
- void loadPredefinedSchema(InputStream schemaStream);
-
/**
* Delete a schema according to its id
*
@@ -100,56 +84,17 @@ public interface SchemaService {
boolean deleteSchema(String schemaId);
/**
- * Delete a schema
- *
- * @param schemaStream inputStream of the schema to delete
- * @return true if the schema has been deleted
- */
- boolean deleteSchema(InputStream schemaStream);
-
- /**
- * Save an extension of a JSON schema
- *
- * @param extensionStream inputStream of the extension
- */
- void saveExtension(InputStream extensionStream) throws IOException;
-
- /**
- * Save an extension of a JSON schema
- *
- * @param extension as String value
- */
- void saveExtension(String extension) throws IOException;
-
- /**
- * Delete an extension
+ * Load a predefined schema into memory
*
- * @param extensionStream inputStream of the extension to delete
- * @return true if the extension has been deleted
+ * @param schemaStream inputStream of the schema
*/
- boolean deleteExtension(InputStream extensionStream) throws IOException;
+ void loadPredefinedSchema(InputStream schemaStream) throws IOException;
/**
- * Delete an extension by an id
+ * unload a predefined schema into memory
*
- * @param extensionId id of the extension
- * @return true if the extension has been deleted
- */
- boolean deleteExtension(String extensionId);
-
- /**
- * Retrieves json schema extension metadatas, ordered according to the specified {@code sortBy} String and and paged: only {@code size}
- * of them
- * are retrieved, starting with the {@code
- * offset}-th one.
- *
- * @param offset zero or a positive integer specifying the position of the first element in the total ordered collection of matching elements
- * @param size a positive integer specifying how many matching elements should be retrieved or {@code -1} if all of them should be retrieved
- * @param sortBy an optional ({@code null} if no sorting is required) String of comma ({@code ,}) separated property names on which ordering should be performed, ordering elements according to the property order in the
- * String, considering each in turn and moving on to the next one in case of equality of all preceding ones. Each property name is optionally followed by
- * a column ({@code :}) and an order specifier: {@code asc} or {@code desc}.
- * @return a {@link PartialList} of json schema extension metadata
+ * @param schemaStream inputStream of the schema to delete
+ * @return true if the schema has been deleted
*/
- PartialList<Metadata> getJsonSchemaExtensionsMetadatas(int offset, int size, String sortBy);
-
+ boolean unloadPredefinedSchema(InputStream schemaStream);
}
diff --git a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java
new file mode 100644
index 000000000..ddd2e4b7d
--- /dev/null
+++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java
@@ -0,0 +1,241 @@
+/*
+ * 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.unomi.schema.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.networknt.schema.*;
+import com.networknt.schema.uri.URIFetcher;
+import org.apache.commons.io.IOUtils;
+import org.apache.unomi.api.Metadata;
+import org.apache.unomi.api.PartialList;
+import org.apache.unomi.api.services.SchedulerService;
+import org.apache.unomi.persistence.spi.PersistenceService;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.apache.unomi.schema.api.SchemaService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+public class SchemaServiceImpl implements SchemaService {
+
+ private static final String URI = "https://json-schema.org/draft/2019-09/schema";
+
+ private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class.getName());
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ private final Map<String, JsonSchemaWrapper> predefinedUnomiJSONSchemaById = new HashMap<>();
+ private Map<String, JsonSchemaWrapper> schemasById = new HashMap<>();
+
+ private Integer jsonSchemaRefreshInterval = 1000;
+ private ScheduledFuture<?> scheduledFuture;
+
+ private BundleContext bundleContext;
+ private PersistenceService persistenceService;
+ private SchedulerService schedulerService;
+ private JsonSchemaFactory jsonSchemaFactory;
+
+
+ @Override
+ public PartialList<Metadata> getJsonSchemaMetadatas(int offset, int size, String sortBy) {
+ PartialList<JsonSchemaWrapper> items = persistenceService.getAllItems(JsonSchemaWrapper.class, offset, size, sortBy);
+ List<Metadata> details = new LinkedList<>();
+ for (JsonSchemaWrapper definition : items.getList()) {
+ details.add(definition.getMetadata());
+ }
+ return new PartialList<>(details, items.getOffset(), items.getPageSize(), items.getTotalSize(), items.getTotalSizeRelation());
+ }
+
+ @Override
+ public boolean isValid(String data, String schemaId) {
+ JsonSchema jsonSchema = null;
+ JsonNode jsonNode = null;
+
+ try {
+ jsonNode = objectMapper.readTree(data);
+ jsonSchema = jsonSchemaFactory.getSchema(new URI(schemaId));
+ } catch (JsonProcessingException | URISyntaxException e) {
+ logger.error("Failed to process data to validate", e);
+ return false;
+ }
+
+ if (jsonNode == null) {
+ logger.warn("No data to validate");
+ return false;
+ }
+
+ if (jsonSchema == null) {
+ logger.warn("No schema found for {}", schemaId);
+ return false;
+ }
+
+ Set<ValidationMessage> validationMessages = jsonSchema.validate(jsonNode);
+ if (validationMessages == null || validationMessages.isEmpty()) {
+ return true;
+ }
+ for (ValidationMessage validationMessage : validationMessages) {
+ logger.error("Error validating object against schema {}: {}", schemaId, validationMessage);
+ }
+ return false;
+ }
+
+ @Override
+ public List<JsonSchemaWrapper> getSchemasByTarget(String target) {
+ return schemasById.values().stream().filter(jsonSchemaWrapper -> jsonSchemaWrapper.getTarget() != null && jsonSchemaWrapper.getTarget().equals(target))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public void saveSchema(String schema) {
+ JsonSchema jsonSchema = jsonSchemaFactory.getSchema(schema);
+ JsonNode schemaNode = jsonSchema.getSchemaNode();
+ String id = schemaNode.get("$id").asText();
+
+ if (!predefinedUnomiJSONSchemaById.containsKey(id)) {
+ String target = schemaNode.at("/self/target").asText();
+ String name = schemaNode.at("/self/name").asText();
+
+ if ("events".equals(target) && !name.matches("[_A-Za-z][_0-9A-Za-z]*")) {
+ throw new IllegalArgumentException(
+ "The \"/self/name\" value should match the following regular expression [_A-Za-z][_0-9A-Za-z]* for the Json schema on events");
+ }
+
+ JsonSchemaWrapper jsonSchemaWrapper = new JsonSchemaWrapper(id, schema, target);
+ persistenceService.save(jsonSchemaWrapper);
+ schemasById.put(id, jsonSchemaWrapper);
+ } else {
+ // TODO we should crash error in case save failed, so that caller can react on save fail and get the reason why using Exceptions
+ logger.error("Trying to save a Json Schema that is using the ID of an existing Json Schema provided by Unomi is forbidden");
+ }
+ }
+
+ @Override
+ public boolean deleteSchema(String schemaId) {
+ // forbidden to delete predefined Unomi schemas
+ if (!predefinedUnomiJSONSchemaById.containsKey(schemaId)) {
+ schemasById.remove(schemaId);
+ return persistenceService.remove(schemaId, JsonSchemaWrapper.class);
+ }
+ return false;
+ }
+
+ @Override
+ public void loadPredefinedSchema(InputStream schemaStream) throws IOException {
+ String jsonSchema = IOUtils.toString(schemaStream);
+
+ // check that schema is valid and get the id
+ JsonNode schemaNode = jsonSchemaFactory.getSchema(jsonSchema).getSchemaNode();
+ String schemaId = schemaNode.get("$id").asText();
+ String target = schemaNode.at("/self/target").asText();
+ JsonSchemaWrapper jsonSchemaWrapper = new JsonSchemaWrapper(schemaId, jsonSchema, target);
+
+ predefinedUnomiJSONSchemaById.put(schemaId, jsonSchemaWrapper);
+ schemasById.put(schemaId, jsonSchemaWrapper);
+ }
+
+ @Override
+ public boolean unloadPredefinedSchema(InputStream schemaStream) {
+ JsonNode schemaNode = jsonSchemaFactory.getSchema(schemaStream).getSchemaNode();
+ String schemaId = schemaNode.get("$id").asText();
+
+ return predefinedUnomiJSONSchemaById.remove(schemaId) != null && schemasById.remove(schemaId) != null;
+ }
+
+ @Override
+ public JsonSchemaWrapper getSchema(String schemaId) {
+ return schemasById.get(schemaId);
+ }
+
+ private URIFetcher getUriFetcher() {
+ return uri -> {
+ logger.debug("Fetching schema {}", uri);
+ JsonSchemaWrapper jsonSchemaWrapper = schemasById.get(uri.toString());
+ if (jsonSchemaWrapper == null) {
+ logger.error("Couldn't find schema {}", uri);
+ return null;
+ }
+ return IOUtils.toInputStream(jsonSchemaWrapper.getSchema());
+ };
+ }
+
+ private void refreshJSONSchemas() {
+ schemasById = new HashMap<>();
+ schemasById.putAll(predefinedUnomiJSONSchemaById);
+
+ persistenceService.getAllItems(JsonSchemaWrapper.class).forEach(
+ JsonSchemaWrapper -> schemasById.put(JsonSchemaWrapper.getId(), JsonSchemaWrapper));
+ }
+
+ private void initializeTimers() {
+ TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+ refreshJSONSchemas();
+ }
+ };
+ scheduledFuture = schedulerService.getScheduleExecutorService()
+ .scheduleWithFixedDelay(task, 0, jsonSchemaRefreshInterval, TimeUnit.MILLISECONDS);
+ }
+
+ public void init() {
+ JsonMetaSchema jsonMetaSchema = JsonMetaSchema.builder(URI, JsonMetaSchema.getV201909())
+ .addKeyword(new NonValidationKeyword("self"))
+ .build();
+
+ jsonSchemaFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909))
+ .addMetaSchema(jsonMetaSchema)
+ .defaultMetaSchemaURI(URI)
+ .uriFetcher(getUriFetcher(), "https", "http")
+ .build();
+
+ initializeTimers();
+ logger.info("Schema service initialized.");
+ }
+
+ public void destroy() {
+ scheduledFuture.cancel(true);
+ logger.info("Schema service shutdown.");
+ }
+
+ public void setPersistenceService(PersistenceService persistenceService) {
+ this.persistenceService = persistenceService;
+ }
+
+ public void setSchedulerService(SchedulerService schedulerService) {
+ this.schedulerService = schedulerService;
+ }
+
+ public void setJsonSchemaRefreshInterval(Integer jsonSchemaRefreshInterval) {
+ this.jsonSchemaRefreshInterval = jsonSchemaRefreshInterval;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+}
diff --git a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/listener/JsonSchemaListener.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/listener/JsonSchemaListener.java
new file mode 100644
index 000000000..9e674d545
--- /dev/null
+++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/listener/JsonSchemaListener.java
@@ -0,0 +1,137 @@
+/*
+ * 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.unomi.schema.listener;
+
+import org.apache.unomi.persistence.spi.PersistenceService;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.apache.unomi.schema.api.SchemaService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+
+/**
+ * An implementation of a BundleListener for the JSON schema.
+ * It will load the pre-defined schema files in the folder META-INF/cxs/schemas.
+ * It will load the extension of schema in the folder META-INF/cxs/schemasextensions.
+ * The scripts will be stored in the ES index jsonSchema and the extension will be stored in jsonSchemaExtension
+ */
+public class JsonSchemaListener implements SynchronousBundleListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(JsonSchemaListener.class.getName());
+ public static final String ENTRIES_LOCATION = "META-INF/cxs/schemas";
+
+ private PersistenceService persistenceService;
+ private SchemaService schemaService;
+ private BundleContext bundleContext;
+
+ public void setPersistenceService(PersistenceService persistenceService) {
+ this.persistenceService = persistenceService;
+ }
+
+ public void setSchemaService(SchemaService schemaService) {
+ this.schemaService = schemaService;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void postConstruct() {
+ logger.info("JSON schema listener initializing...");
+ logger.debug("postConstruct {}", bundleContext.getBundle());
+ createIndexes();
+
+ loadPredefinedSchemas(bundleContext, true);
+
+ for (Bundle bundle : bundleContext.getBundles()) {
+ if (bundle.getBundleContext() != null && bundle.getBundleId() != bundleContext.getBundle().getBundleId()) {
+ loadPredefinedSchemas(bundle.getBundleContext(), true);
+ }
+ }
+
+ bundleContext.addBundleListener(this);
+ logger.info("JSON schema listener initialized.");
+ }
+
+ public void preDestroy() {
+ bundleContext.removeBundleListener(this);
+ logger.info("JSON schema listener shutdown.");
+ }
+
+ private void processBundleStartup(BundleContext bundleContext) {
+ if (bundleContext == null) {
+ return;
+ }
+ loadPredefinedSchemas(bundleContext, true);
+ }
+
+ private void processBundleStop(BundleContext bundleContext) {
+ if (bundleContext == null) {
+ return;
+ }
+ loadPredefinedSchemas(bundleContext, false);
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ switch (event.getType()) {
+ case BundleEvent.STARTED:
+ processBundleStartup(event.getBundle().getBundleContext());
+ break;
+ case BundleEvent.STOPPING:
+ if (!event.getBundle().getSymbolicName().equals(bundleContext.getBundle().getSymbolicName())) {
+ processBundleStop(event.getBundle().getBundleContext());
+ }
+ break;
+ }
+ }
+
+ public void createIndexes() {
+ if (persistenceService.createIndex(JsonSchemaWrapper.ITEM_TYPE)) {
+ logger.info("{} index created", JsonSchemaWrapper.ITEM_TYPE);
+ } else {
+ logger.info("{} index already exists", JsonSchemaWrapper.ITEM_TYPE);
+ }
+ }
+
+ private void loadPredefinedSchemas(BundleContext bundleContext, boolean load) {
+ Enumeration<URL> predefinedSchemas = bundleContext.getBundle().findEntries(ENTRIES_LOCATION, "*.json", true);
+ if (predefinedSchemas == null) {
+ return;
+ }
+
+ while (predefinedSchemas.hasMoreElements()) {
+ URL predefinedSchemaURL = predefinedSchemas.nextElement();
+ logger.debug("Found predefined JSON schema at {}, {}... ", predefinedSchemaURL, load ? "loading" : "unloading");
+ try (InputStream schemaInputStream = predefinedSchemaURL.openStream()) {
+ if (load) {
+ schemaService.loadPredefinedSchema(schemaInputStream);
+ } else {
+ schemaService.unloadPredefinedSchema(schemaInputStream);
+ }
+ } catch (Exception e) {
+ logger.error("Error while {} schema definition {}", load ? "loading" : "unloading", predefinedSchemaURL, e);
+ }
+ }
+ }
+}
diff --git a/services/src/main/resources/META-INF/cxs/schemas/condition.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/condition.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/condition.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/condition.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/conditiontype.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/conditiontype.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/conditiontype.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/conditiontype.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/consent.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/consent.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/consent.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/consent.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/consentType.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/consentType.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/consentType.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/consentType.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/customitem.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/customitem.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/customitem.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/customitem.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/customitems/page.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/customitems/page.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/customitems/page.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/customitems/page.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/customitems/site.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/customitems/site.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/customitems/site.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/customitems/site.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/event.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/event.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/event.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/event.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/anonymizeProfile.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/anonymizeProfile.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/anonymizeProfile.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/anonymizeProfile.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/articleCompleted.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/articleCompleted.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/articleCompleted.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/articleCompleted.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/form.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/form.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/form.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/form.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/goal.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/goal.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/goal.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/goal.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/identify.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/identify.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/identify.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/identify.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/incrementInterest.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/incrementInterest.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/incrementInterest.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/incrementInterest.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/login.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/login.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/login.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/login.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/modifyConsent.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/modifyConsent.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/modifyConsent.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/modifyConsent.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/profileDeleted.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/profileDeleted.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/profileDeleted.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/profileDeleted.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/profileUpdated.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/profileUpdated.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/profileUpdated.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/profileUpdated.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/ruleFired.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/ruleFired.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/ruleFired.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/ruleFired.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/search.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/search.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/sessionCreated.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/sessionCreated.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/sessionCreated.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/sessionCreated.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/sessionReassigned.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/sessionReassigned.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/sessionReassigned.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/sessionReassigned.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/updateProperties.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/updateProperties.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/updateProperties.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/updateProperties.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/view.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/view.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/events/view.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/view.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/goal.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/goal.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/goal.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/goal.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/item.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/item.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/item.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/item.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/metadata.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/metadata.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/metadata.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/metadata.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/metadataitem.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/metadataitem.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/metadataitem.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/metadataitem.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/parameter.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/parameter.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/parameter.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/parameter.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/personalization/filter.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/filter.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/personalization/filter.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/filter.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/personalization/personalizationrequest.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/personalizationrequest.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/personalization/personalizationrequest.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/personalizationrequest.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/personalization/personalizedcontent.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/personalizedcontent.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/personalization/personalizedcontent.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/personalizedcontent.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/personalization/target.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/target.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/personalization/target.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/personalization/target.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/profile.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/profile.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/profile.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/profile.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/session.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/session.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/session.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/session.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/timestampeditem.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/timestampeditem.json
similarity index 50%
rename from services/src/main/resources/META-INF/cxs/schemas/timestampeditem.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/timestampeditem.json
index b4e1528d3..d7fa16343 100644
--- a/services/src/main/resources/META-INF/cxs/schemas/timestampeditem.json
+++ b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/timestampeditem.json
@@ -4,10 +4,21 @@
"title": "TimestampedItem",
"type": "object",
"allOf": [{ "$ref": "https://unomi.apache.org/schemas/json/item/1-0-0" }],
- "properties" : {
- "timeStamp" : {
- "type" : ["string"],
- "format" : "date-time"
+ "oneOf": [
+ {
+ "properties" : {
+ "timeStamp" : {
+ "type" : "string",
+ "format" : "date-time"
+ }
+ }
+ },
+ {
+ "properties" : {
+ "timeStamp" : {
+ "type" : "integer"
+ }
+ }
}
- }
+ ]
}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/boolean.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/boolean.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/boolean.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/boolean.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/date.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/date.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/date.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/date.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/email.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/email.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/email.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/email.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/integer.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/integer.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/integer.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/integer.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/long.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/long.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/long.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/long.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/set.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/set.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/set.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/set.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/values/string.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/string.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/values/string.json
rename to extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/values/string.json
diff --git a/extensions/json-schema/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/extensions/json-schema/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..02e3280c0
--- /dev/null
+++ b/extensions/json-schema/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,54 @@
+<?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.
+ -->
+
+<blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+ xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+ <cm:property-placeholder persistent-id="org.apache.unomi.schema" update-strategy="reload">
+ <cm:default-properties>
+ <cm:property name="json.schema.refresh.interval" value="1000"/>
+ </cm:default-properties>
+ </cm:property-placeholder>
+
+ <reference id="profileService" interface="org.apache.unomi.api.services.ProfileService"/>
+ <reference id="persistenceService" interface="org.apache.unomi.persistence.spi.PersistenceService"/>
+ <reference id="schedulerService" interface="org.apache.unomi.api.services.SchedulerService"/>
+
+ <bean id="schemaServiceImpl" class="org.apache.unomi.schema.impl.SchemaServiceImpl" init-method="init"
+ destroy-method="destroy">
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ <property name="persistenceService" ref="persistenceService"/>
+ <property name="schedulerService" ref="schedulerService"/>
+ <property name="jsonSchemaRefreshInterval" value="${json.schema.refresh.interval}"/>
+ </bean>
+ <service id="schemaService" ref="schemaServiceImpl" interface="org.apache.unomi.schema.api.SchemaService"/>
+
+ <bean id="jsonSchemaListenerImpl" class="org.apache.unomi.schema.listener.JsonSchemaListener"
+ init-method="postConstruct" destroy-method="preDestroy">
+ <property name="persistenceService" ref="persistenceService"/>
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ <property name="schemaService" ref="schemaServiceImpl"/>
+ </bean>
+ <service id="jsonSchemaListener" ref="jsonSchemaListenerImpl">
+ <interfaces>
+ <value>org.osgi.framework.SynchronousBundleListener</value>
+ </interfaces>
+ </service>
+</blueprint>
diff --git a/extensions/json-schema/services/src/main/resources/org.apache.unomi.schema.cfg b/extensions/json-schema/services/src/main/resources/org.apache.unomi.schema.cfg
new file mode 100644
index 000000000..b930b866f
--- /dev/null
+++ b/extensions/json-schema/services/src/main/resources/org.apache.unomi.schema.cfg
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+# The interval in milliseconds to reload the json schemas in memory
+services.json.schema.refresh.interval=${org.apache.unomi.json.schema.refresh.interval:-1000}
\ No newline at end of file
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 70105e5f5..5b7c58d8c 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -40,6 +40,7 @@
<module>weather-update</module>
<module>web-tracker</module>
<module>groovy-actions</module>
+ <module>json-schema</module>
</modules>
</project>
diff --git a/graphql/cxs-impl/pom.xml b/graphql/cxs-impl/pom.xml
index d79a7cef2..3ff2923cf 100644
--- a/graphql/cxs-impl/pom.xml
+++ b/graphql/cxs-impl/pom.xml
@@ -149,6 +149,12 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-json-schema-services</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java
index eff196418..84b9ec8bc 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java
@@ -16,6 +16,8 @@
*/
package org.apache.unomi.graphql.schema;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.networknt.schema.JsonSchema;
import graphql.annotations.AnnotationsSchemaCreator;
import graphql.annotations.processor.GraphQLAnnotations;
import graphql.annotations.processor.ProcessingElementsContainer;
@@ -34,11 +36,10 @@ import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLType;
import graphql.schema.visibility.GraphqlFieldVisibility;
import org.apache.unomi.api.PropertyType;
-import org.apache.unomi.api.schema.json.JSONObjectType;
-import org.apache.unomi.api.schema.json.JSONSchema;
-import org.apache.unomi.api.schema.json.JSONType;
+import org.apache.unomi.graphql.schema.json.JSONObjectType;
+import org.apache.unomi.graphql.schema.json.JSONSchema;
+import org.apache.unomi.graphql.schema.json.JSONType;
import org.apache.unomi.api.services.ProfileService;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.graphql.CDPGraphQLConstants;
import org.apache.unomi.graphql.converters.UnomiToGraphQLConverter;
import org.apache.unomi.graphql.fetchers.CustomEventOrSetPropertyDataFetcher;
@@ -55,6 +56,7 @@ import org.apache.unomi.graphql.providers.GraphQLMutationProvider;
import org.apache.unomi.graphql.providers.GraphQLQueryProvider;
import org.apache.unomi.graphql.providers.GraphQLSubscriptionProvider;
import org.apache.unomi.graphql.providers.GraphQLTypeFunctionProvider;
+import org.apache.unomi.graphql.schema.json.JSONTypeFactory;
import org.apache.unomi.graphql.types.input.CDPEventFilterInput;
import org.apache.unomi.graphql.types.input.CDPEventInput;
import org.apache.unomi.graphql.types.input.CDPEventProcessor;
@@ -69,8 +71,11 @@ import org.apache.unomi.graphql.types.output.CDPPersona;
import org.apache.unomi.graphql.types.output.CDPProfile;
import org.apache.unomi.graphql.types.output.RootMutation;
import org.apache.unomi.graphql.types.output.RootQuery;
+import org.apache.unomi.graphql.utils.GraphQLObjectMapper;
import org.apache.unomi.graphql.utils.ReflectionUtil;
import org.apache.unomi.graphql.utils.StringUtils;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.apache.unomi.schema.api.SchemaService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -331,7 +336,8 @@ public class GraphQLSchemaProvider {
}
private void registerDynamicUnomiInputEvents(GraphQLSchema.Builder schemaBuilder) {
- final List<JSONSchema> unomiEventTypes = schemaService.getSchemasByTarget("events");
+ final List<JSONSchema> unomiEventTypes = schemaService.getSchemasByTarget("events").stream()
+ .map(jsonSchemaWrapper -> buildJSONSchema(jsonSchemaWrapper, schemaService)).collect(Collectors.toList());
if (!unomiEventTypes.isEmpty()) {
for (JSONSchema unomiEventType : unomiEventTypes) {
@@ -353,7 +359,8 @@ public class GraphQLSchemaProvider {
}
private void registerDynamicUnomiOutputEvents(GraphQLSchema.Builder schemaBuilder) {
- final List<JSONSchema> unomiEventTypes = schemaService.getSchemasByTarget("events");
+ final List<JSONSchema> unomiEventTypes = schemaService.getSchemasByTarget("events").stream()
+ .map(jsonSchemaWrapper -> buildJSONSchema(jsonSchemaWrapper, schemaService)).collect(Collectors.toList());
if (!unomiEventTypes.isEmpty()) {
final GraphQLCodeRegistry.Builder codeRegisterBuilder = graphQLAnnotations.getContainer().getCodeRegistryBuilder();
@@ -650,7 +657,8 @@ public class GraphQLSchemaProvider {
}
// now add all unomi defined event types
- final List<JSONSchema> unomiEventTypes = schemaService.getSchemasByTarget("events");
+ final List<JSONSchema> unomiEventTypes = schemaService.getSchemasByTarget("events").stream()
+ .map(jsonSchemaWrapper -> buildJSONSchema(jsonSchemaWrapper, schemaService)).collect(Collectors.toList());
unomiEventTypes.forEach(eventType -> {
final String typeName = UnomiToGraphQLConverter.convertEventType(eventType.getName());
final GraphQLInputType eventInputType = (GraphQLInputType) getFromTypeRegistry(typeName + "Input");
@@ -668,6 +676,17 @@ public class GraphQLSchemaProvider {
registerInTypeRegistry(CDPEventInput.TYPE_NAME, builder.build());
}
+ public static JSONSchema buildJSONSchema(JsonSchemaWrapper jsonSchemaWrapper, SchemaService schemaService) {
+ Map<String, Object> schemaMap;
+ try {
+ schemaMap = GraphQLObjectMapper.getInstance().readValue(jsonSchemaWrapper.getSchema(), Map.class);
+ } catch (JsonProcessingException e) {
+ logger.error("Failed to process Json object, e");
+ schemaMap = Collections.emptyMap();
+ }
+ return new JSONSchema(schemaMap, new JSONTypeFactory(schemaService));
+ }
+
private void registerDynamicEventFilterInputFields() {
final List<GraphQLInputObjectField> fieldDefinitions = new ArrayList<>();
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java
index 7d6198d93..37cd40a09 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java
@@ -21,7 +21,6 @@ import graphql.execution.SubscriptionExecutionStrategy;
import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLSchema;
import org.apache.unomi.api.services.ProfileService;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.graphql.fetchers.event.UnomiEventPublisher;
import org.apache.unomi.graphql.providers.GraphQLAdditionalTypesProvider;
import org.apache.unomi.graphql.providers.GraphQLCodeRegistryProvider;
@@ -37,6 +36,7 @@ import org.apache.unomi.graphql.types.output.CDPPersona;
import org.apache.unomi.graphql.types.output.CDPProfile;
import org.apache.unomi.graphql.types.output.CDPProfileInterface;
import org.apache.unomi.graphql.types.output.CDPPropertyInterface;
+import org.apache.unomi.schema.api.SchemaService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONArrayType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONArrayType.java
similarity index 96%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONArrayType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONArrayType.java
index aa8cc2a34..427b31e18 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONArrayType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONArrayType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.List;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONBooleanType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONBooleanType.java
similarity index 95%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONBooleanType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONBooleanType.java
index aea431e78..79f541ec7 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONBooleanType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONBooleanType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONEnumType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONEnumType.java
similarity index 95%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONEnumType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONEnumType.java
index 57ba1e668..6cee489a9 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONEnumType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONEnumType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONIntegerType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONIntegerType.java
similarity index 95%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONIntegerType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONIntegerType.java
index 9ae40dd84..e873d12fb 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONIntegerType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONIntegerType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONNullType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONNullType.java
similarity index 95%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONNullType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONNullType.java
index 809a29fea..3cdd3ce5a 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONNullType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONNullType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONNumberType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONNumberType.java
similarity index 95%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONNumberType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONNumberType.java
index d5917772f..6233217d7 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONNumberType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONNumberType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONObjectType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONObjectType.java
similarity index 97%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONObjectType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONObjectType.java
index da28f41e3..be91e0a2b 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONObjectType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONObjectType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.HashMap;
import java.util.List;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONSchema.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONSchema.java
similarity index 98%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONSchema.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONSchema.java
index 1e65f8e6e..fe159b0a0 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONSchema.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONSchema.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import org.apache.unomi.api.PluginType;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONStringType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONStringType.java
similarity index 95%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONStringType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONStringType.java
index c63f6b5c5..238c61853 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONStringType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONStringType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.Map;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONType.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONType.java
similarity index 98%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONType.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONType.java
index d1c047438..2f8afa290 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONType.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONType.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
import java.util.ArrayList;
import java.util.List;
diff --git a/api/src/main/java/org/apache/unomi/api/schema/json/JSONTypeFactory.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONTypeFactory.java
similarity index 89%
rename from api/src/main/java/org/apache/unomi/api/schema/json/JSONTypeFactory.java
rename to graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONTypeFactory.java
index 33f4b72fb..6b1ab8255 100644
--- a/api/src/main/java/org/apache/unomi/api/schema/json/JSONTypeFactory.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/json/JSONTypeFactory.java
@@ -14,9 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.unomi.api.schema.json;
+package org.apache.unomi.graphql.schema.json;
-import org.apache.unomi.api.services.SchemaService;
+import org.apache.unomi.graphql.schema.GraphQLSchemaProvider;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.apache.unomi.schema.api.SchemaService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,9 +51,9 @@ public class JSONTypeFactory {
List<JSONType> getTypes(Map<String, Object> schemaTree) {
if (schemaTree.containsKey("$ref")) {
String schemaId = (String) schemaTree.get("$ref");
- JSONSchema refSchema = schemaService.getSchema(schemaId);
+ JsonSchemaWrapper refSchema = schemaService.getSchema(schemaId);
if (refSchema != null) {
- schemaTree = refSchema.getSchemaTree();
+ schemaTree = GraphQLSchemaProvider.buildJSONSchema(refSchema, schemaService).getSchemaTree();
} else {
System.err.println("Couldn't find schema for ref " + schemaId);
}
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/resolvers/CDPEventInterfaceResolver.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/resolvers/CDPEventInterfaceResolver.java
index 2d6cebbdd..1ded2441a 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/resolvers/CDPEventInterfaceResolver.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/resolvers/CDPEventInterfaceResolver.java
@@ -18,11 +18,13 @@ package org.apache.unomi.graphql.types.resolvers;
import graphql.TypeResolutionEnvironment;
import graphql.schema.GraphQLObjectType;
-import org.apache.unomi.api.schema.json.JSONSchema;
-import org.apache.unomi.api.services.SchemaService;
+import org.apache.unomi.graphql.schema.GraphQLSchemaProvider;
+import org.apache.unomi.graphql.schema.json.JSONSchema;
import org.apache.unomi.graphql.converters.UnomiToGraphQLConverter;
import org.apache.unomi.graphql.services.ServiceManager;
import org.apache.unomi.graphql.types.output.CDPEventInterface;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.apache.unomi.schema.api.SchemaService;
public class CDPEventInterfaceResolver extends BaseTypeResolver {
@@ -32,11 +34,10 @@ public class CDPEventInterfaceResolver extends BaseTypeResolver {
SchemaService schemaService = serviceManager.getService(SchemaService.class);
final CDPEventInterface eventInterface = env.getObject();
- final JSONSchema eventSchema =
- schemaService.getSchema("https://unomi.apache.org/schemas/json/events/" + eventInterface.getEvent().getEventType() + "/1-0"
- + "-0");
+ final JsonSchemaWrapper eventSchema = schemaService.getSchema("https://unomi.apache.org/schemas/json/events/" + eventInterface.getEvent().getEventType() + "/1-0-0");
if (eventSchema != null) {
- final String typeName = UnomiToGraphQLConverter.convertEventType(eventSchema.getName());
+ final JSONSchema jsonSchema = GraphQLSchemaProvider.buildJSONSchema(eventSchema, schemaService);
+ final String typeName = UnomiToGraphQLConverter.convertEventType(jsonSchema.getName());
return env.getSchema().getObjectType(typeName);
} else {
return super.getType(env);
diff --git a/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java b/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java
index 5b14aa7c0..e3fc2c40c 100644
--- a/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java
@@ -19,10 +19,9 @@ package org.apache.unomi.itests;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.entity.ContentType;
-import org.apache.unomi.api.schema.UnomiJSONSchema;
-import org.apache.unomi.api.schema.JSONSchemaExtension;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.persistence.spi.PersistenceService;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.apache.unomi.schema.api.SchemaService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -50,7 +49,6 @@ import static org.junit.Assert.assertTrue;
@ExamReactorStrategy(PerSuite.class)
public class JSONSchemaIT extends BaseIT {
private final static String JSONSCHEMA_URL = "/cxs/jsonSchema";
- private final static String JSONSCHEMAEXTENSION_URL = "/cxs/jsonSchemaExtension";
private static final int DEFAULT_TRYING_TIMEOUT = 2000;
private static final int DEFAULT_TRYING_TRIES = 30;
@@ -66,14 +64,11 @@ public class JSONSchemaIT extends BaseIT {
public void setUp() throws InterruptedException {
keepTrying("Couldn't find json schema endpoint", () -> get(JSONSCHEMA_URL, List.class), Objects::nonNull, DEFAULT_TRYING_TIMEOUT,
DEFAULT_TRYING_TRIES);
- keepTrying("Couldn't find json schema extension endpoint", () -> get(JSONSCHEMAEXTENSION_URL, List.class), Objects::nonNull,
- DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
}
@After
public void tearDown() {
schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/testEventType/1-0-0");
- schemaService.deleteExtension("extension-test-event-1");
}
@Test
@@ -92,7 +87,7 @@ public class JSONSchemaIT extends BaseIT {
@Test
public void testSaveNewValidJSONSchema() throws InterruptedException {
- assertTrue("JSON schema list should be empty", persistenceService.getAllItems(UnomiJSONSchema.class).isEmpty());
+ assertTrue("JSON schema list should be empty", persistenceService.getAllItems(JsonSchemaWrapper.class).isEmpty());
CloseableHttpResponse response = post(JSONSCHEMA_URL, "schemas/events/test-event-type.json", ContentType.TEXT_PLAIN);
@@ -104,7 +99,7 @@ public class JSONSchemaIT extends BaseIT {
@Test
public void testDeleteJSONSchema() throws InterruptedException {
- assertTrue("JSON schema list should be empty", persistenceService.getAllItems(UnomiJSONSchema.class).isEmpty());
+ assertTrue("JSON schema list should be empty", persistenceService.getAllItems(JsonSchemaWrapper.class).isEmpty());
post(JSONSCHEMA_URL, "schemas/events/test-event-type.json", ContentType.TEXT_PLAIN);
@@ -124,7 +119,7 @@ public class JSONSchemaIT extends BaseIT {
@Test
public void testSaveNewInvalidJSONSchema() throws IOException {
- assertTrue("JSON schema list should be empty", persistenceService.getAllItems(UnomiJSONSchema.class).isEmpty());
+ assertTrue("JSON schema list should be empty", persistenceService.getAllItems(JsonSchemaWrapper.class).isEmpty());
try (CloseableHttpResponse response = post(JSONSCHEMA_URL, "schemas/events/test-invalid.json", ContentType.TEXT_PLAIN)) {
assertEquals("Save should have failed", 500, response.getStatusLine().getStatusCode());
}
@@ -132,52 +127,9 @@ public class JSONSchemaIT extends BaseIT {
@Test
public void testSaveSchemaWithInvalidName() throws IOException {
- assertTrue("JSON schema list should be empty", persistenceService.getAllItems(UnomiJSONSchema.class).isEmpty());
+ assertTrue("JSON schema list should be empty", persistenceService.getAllItems(JsonSchemaWrapper.class).isEmpty());
try (CloseableHttpResponse response = post(JSONSCHEMA_URL, "schemas/events/test-invalid-name.json", ContentType.TEXT_PLAIN)) {
assertEquals("Save should have failed", 500, response.getStatusLine().getStatusCode());
}
}
- @Test
- public void testGetJsonSchemaExtensionsMetadatas() throws InterruptedException {
- List jsonSchemaExtensions = get(JSONSCHEMAEXTENSION_URL, List.class);
- assertTrue("JSON schema extension list should be empty", jsonSchemaExtensions.isEmpty());
-
- post(JSONSCHEMAEXTENSION_URL, "schemas/extension/extension-test-event-example.json", ContentType.TEXT_PLAIN);
-
- jsonSchemaExtensions = keepTrying("Couldn't find json extensions", () -> get(JSONSCHEMAEXTENSION_URL, List.class),
- (list) -> !list.isEmpty(), DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
- assertFalse("JSON schema list should not be empty", jsonSchemaExtensions.isEmpty());
- assertEquals("JSON schema list should not be empty", 1, jsonSchemaExtensions.size());
- }
-
- @Test
- public void testSaveNewJSONSchemaExtension() throws InterruptedException {
-
- assertTrue("JSON schema list should be empty", persistenceService.getAllItems(JSONSchemaExtension.class).isEmpty());
-
- CloseableHttpResponse response = post(JSONSCHEMAEXTENSION_URL, "schemas/extension/extension-test-event-example.json",
- ContentType.TEXT_PLAIN);
-
- assertEquals("Invalid response code", 200, response.getStatusLine().getStatusCode());
-
- keepTrying("Couldn't find json schemas extensions", () -> get(JSONSCHEMAEXTENSION_URL, List.class), (list) -> !list.isEmpty(),
- DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
- }
-
- @Test
- public void testDeleteJSONSchemaExtension() throws InterruptedException {
- assertTrue("JSON schema list should be empty", persistenceService.getAllItems(JSONSchemaExtension.class).isEmpty());
-
- post(JSONSCHEMAEXTENSION_URL, "schemas/extension/extension-test-event-example.json", ContentType.TEXT_PLAIN);
-
- keepTrying("Couldn't find json schemas extension", () -> get(JSONSCHEMAEXTENSION_URL, List.class), (list) -> !list.isEmpty(),
- DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
-
- CloseableHttpResponse response = delete(JSONSCHEMAEXTENSION_URL + "/extension-test-event-1");
- assertEquals("Invalid response code", 204, response.getStatusLine().getStatusCode());
-
- keepTrying("wait for empty list of schemas extensions", () -> get(JSONSCHEMAEXTENSION_URL, List.class), List::isEmpty,
- DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
- }
-
}
diff --git a/itests/src/test/resources/schemas/extension/extension-test-event-example.json b/itests/src/test/resources/schemas/extension/extension-test-event-example.json
deleted file mode 100644
index e03feccd8..000000000
--- a/itests/src/test/resources/schemas/extension/extension-test-event-example.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "id": "extension-test-event-1",
- "schemaId": "https://unomi.apache.org/schemas/json/events/test-event-type/1-0-0",
- "description": "An event for example",
- "name": "Name of the event",
- "priority": 10,
- "extension": {
- "allOf": [
- {
- "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0"
- }
- ],
- "properties": {
- "properties": {
- "type": "object",
- "properties": {
- "floatProperty": {
- "type": "number",
- "maximum": "100",
- "description": "Extension of float property"
- }
- }
- }
- }
- }
-}
diff --git a/kar/pom.xml b/kar/pom.xml
index f25e555f9..23824b273 100644
--- a/kar/pom.xml
+++ b/kar/pom.xml
@@ -114,6 +114,11 @@
<artifactId>cxs-geonames-rest</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-json-schema-services</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.unomi</groupId>
<artifactId>unomi-groovy-actions-services</artifactId>
diff --git a/kar/src/main/feature/feature.xml b/kar/src/main/feature/feature.xml
index 3b0d695ea..704061013 100644
--- a/kar/src/main/feature/feature.xml
+++ b/kar/src/main/feature/feature.xml
@@ -45,6 +45,7 @@
<configfile finalname="/etc/hazelcast.xml">mvn:org.apache.unomi/unomi-services/${project.version}/xml/hazelcastconfig</configfile>
<configfile finalname="/etc/org.apache.unomi.geonames.cfg">mvn:org.apache.unomi/cxs-geonames-services/${project.version}/cfg/geonamescfg</configfile>
<configfile finalname="/etc/org.apache.unomi.groovy.actions.cfg">mvn:org.apache.unomi/unomi-groovy-actions-services/${project.version}/cfg/groovyactionscfg</configfile>
+ <configfile finalname="/etc/org.apache.unomi.schema.cfg">mvn:org.apache.unomi/unomi-json-schema-services/${project.version}/cfg/schemacfg</configfile>
<bundle start-level="75">mvn:commons-io/commons-io/2.4</bundle>
<bundle start-level="75">mvn:com.fasterxml.jackson.core/jackson-core/${version.jackson.core}</bundle>
<bundle start-level="75">mvn:com.github.fge/btf/1.2</bundle>
@@ -72,6 +73,8 @@
<bundle start-level="75" start="false">mvn:org.apache.unomi/unomi-persistence-spi/${project.version}</bundle>
<bundle start-level="76" start="false">mvn:org.apache.unomi/unomi-persistence-elasticsearch-core/${project.version}</bundle>
<bundle start-level="77" start="false">mvn:org.apache.unomi/unomi-services/${project.version}</bundle>
+ <bundle start-level="77" start="false">mvn:org.apache.unomi/unomi-json-schema-services/${project.version}</bundle>
+ <bundle start-level="77" start="false">mvn:org.apache.unomi/unomi-json-schema-rest/${project.version}</bundle>
<bundle start-level="77" start="false">mvn:org.apache.unomi/cxs-lists-extension-services/${project.version}</bundle>
<bundle start-level="77" start="false">mvn:org.apache.unomi/cxs-lists-extension-rest/${project.version}</bundle>
<bundle start-level="77" start="false">mvn:org.apache.unomi/cxs-geonames-services/${project.version}</bundle>
diff --git a/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 050a2ae19..4eb80acb1 100644
--- a/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -49,6 +49,8 @@
<entry key="org.apache.unomi.cxs-geonames-rest" value="false"/>
<entry key="org.apache.unomi.cxs-privacy-extension-services" value="false"/>
<entry key="org.apache.unomi.cxs-privacy-extension-rest" value="false"/>
+ <entry key="org.apache.unomi.json-schema-services" value="false"/>
+ <entry key="org.apache.unomi.json-schema-rest" value="false"/>
<entry key="org.apache.unomi.rest" value="false"/>
<entry key="org.apache.unomi.wab" value="false"/>
<entry key="org.apache.unomi.plugins-base" value="false"/>
diff --git a/rest/pom.xml b/rest/pom.xml
index 77ae8fc83..6631e9f72 100644
--- a/rest/pom.xml
+++ b/rest/pom.xml
@@ -43,6 +43,12 @@
<artifactId>unomi-persistence-spi</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-json-schema-services</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
diff --git a/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java b/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java
index ad3394596..ba9d9aa50 100644
--- a/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java
+++ b/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java
@@ -27,8 +27,8 @@ import org.apache.unomi.api.Event;
import org.apache.unomi.api.Item;
import org.apache.unomi.api.Profile;
import org.apache.unomi.api.services.PersonalizationService;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.rest.exception.InvalidRequestException;
+import org.apache.unomi.schema.api.SchemaService;
import java.io.IOException;
import java.util.ArrayList;
@@ -55,7 +55,7 @@ public class ContextRequestDeserializer extends StdDeserializer<ContextRequest>
public ContextRequest deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
// Validate schema on it
- if (!schemaService.isValid(node, "https://unomi.apache.org/schemas/json/contextrequest/1-0-0")) {
+ if (!schemaService.isValid(node.toString(), "https://unomi.apache.org/schemas/json/contextrequest/1-0-0")) {
throw new InvalidRequestException("Invalid Context request object", "Invalid received data");
}
ContextRequest cr = new ContextRequest();
@@ -86,7 +86,7 @@ public class ContextRequestDeserializer extends StdDeserializer<ContextRequest>
ArrayNode events = (ArrayNode) eventsNode;
List<Event> filteredEvents = new ArrayList<>();
for (JsonNode event : events) {
- if (schemaService.isValid(event, "https://unomi.apache.org/schemas/json/events/" + event.get("eventType").textValue() + "/1-0-0")) {
+ if (schemaService.isValid(event.toString(), "https://unomi.apache.org/schemas/json/events/" + event.get("eventType").textValue() + "/1-0-0")) {
filteredEvents.add(jsonParser.getCodec().treeToValue(event, Event.class));
}
}
diff --git a/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java b/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java
index 0f234192e..20d808d8a 100644
--- a/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java
+++ b/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java
@@ -24,8 +24,8 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.apache.unomi.api.Event;
import org.apache.unomi.api.EventsCollectorRequest;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.rest.exception.InvalidRequestException;
+import org.apache.unomi.schema.api.SchemaService;
import java.io.IOException;
import java.util.ArrayList;
@@ -50,7 +50,7 @@ public class EventsCollectorRequestDeserializer extends StdDeserializer<EventsCo
@Override
public EventsCollectorRequest deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
- if (!schemaService.isValid(node, "https://unomi.apache.org/schemas/json/eventscollectorrequest/1-0-0")) {
+ if (!schemaService.isValid(node.toString(), "https://unomi.apache.org/schemas/json/eventscollectorrequest/1-0-0")) {
throw new InvalidRequestException("Invalid events collector object", "Invalid received data");
}
@@ -59,7 +59,7 @@ public class EventsCollectorRequestDeserializer extends StdDeserializer<EventsCo
final JsonNode eventsNode = node.get("events");
if (eventsNode instanceof ArrayNode) {
for (JsonNode event : eventsNode) {
- if (schemaService.isValid(event, "https://unomi.apache.org/schemas/json/events/" + event.get("eventType").textValue() + "/1-0-0")) {
+ if (schemaService.isValid(event.toString(), "https://unomi.apache.org/schemas/json/events/" + event.get("eventType").textValue() + "/1-0-0")) {
filteredEvents.add(jsonParser.getCodec().treeToValue(event, Event.class));
}
}
diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java
index 324216586..3f84bf15b 100644
--- a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java
+++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java
@@ -18,7 +18,6 @@
package org.apache.unomi.rest.endpoints;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;
@@ -26,10 +25,10 @@ import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
import org.apache.unomi.api.*;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.api.services.*;
-import org.apache.unomi.api.utils.ValidationPattern;
import org.apache.unomi.persistence.spi.CustomObjectMapper;
import org.apache.unomi.rest.exception.InvalidRequestException;
import org.apache.unomi.rest.service.RestServiceUtils;
+import org.apache.unomi.schema.api.SchemaService;
import org.apache.unomi.utils.Changes;
import org.apache.unomi.utils.HttpUtils;
import org.osgi.service.component.annotations.Component;
@@ -43,8 +42,6 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-import javax.validation.constraints.Pattern;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
@@ -57,7 +54,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import java.util.Objects;
@WebService
@Consumes(MediaType.APPLICATION_JSON)
@@ -164,7 +160,7 @@ public class ContextJsonEndpoint {
if (sessionId != null) {
paramsAsJson.put("sessionId", sessionId);
}
- if (!schemaService.isValid(paramsAsJson, "https://unomi.apache.org/schemas/json/contextrequestparams/1-0-0")) {
+ if (!schemaService.isValid(paramsAsJson.toString(), "https://unomi.apache.org/schemas/json/contextrequestparams/1-0-0")) {
throw new InvalidRequestException("Invalid parameter", "Invalid received data");
}
Date timestamp = new Date();
diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/JsonSchemaExtensionEndPoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/JsonSchemaExtensionEndPoint.java
deleted file mode 100644
index 5033124e8..000000000
--- a/rest/src/main/java/org/apache/unomi/rest/endpoints/JsonSchemaExtensionEndPoint.java
+++ /dev/null
@@ -1,109 +0,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.
- */
-
-package org.apache.unomi.rest.endpoints;
-
-import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
-import org.apache.unomi.api.Metadata;
-import org.apache.unomi.api.services.SchemaService;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jws.WebMethod;
-import javax.jws.WebService;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.io.IOException;
-import java.util.List;
-
-@WebService
-@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
-@CrossOriginResourceSharing(allowAllOrigins = true, allowCredentials = true)
-@Path("/jsonSchemaExtension")
-@Component(service = JsonSchemaExtensionEndPoint.class, property = "osgi.jaxrs.resource=true")
-public class JsonSchemaExtensionEndPoint {
-
- private static final Logger logger = LoggerFactory.getLogger(JsonSchemaExtensionEndPoint.class.getName());
-
- @Reference
- private SchemaService schemaService;
-
- public JsonSchemaExtensionEndPoint() {
- logger.info("Initializing JSON schema extension endpoint...");
- }
-
- @WebMethod(exclude = true)
- public void setSchemaService(SchemaService schemaService) {
- this.schemaService = schemaService;
- }
-
- /**
- * Retrieves the 50 first json schema extension metadatas by default.
- *
- * @param offset zero or a positive integer specifying the position of the first element in the total ordered collection of matching elements
- * @param size a positive integer specifying how many matching elements should be retrieved or {@code -1} if all of them should be retrieved
- * @param sortBy an optional ({@code null} if no sorting is required) String of comma ({@code ,}) separated property names on which ordering should be performed, ordering
- * elements according to the property order in the
- * String, considering each in turn and moving on to the next one in case of equality of all preceding ones. Each property name is optionally followed by
- * a column ({@code :}) and an order specifier: {@code asc} or {@code desc}.
- * @return a List of the 50 first json schema metadata
- */
- @GET
- @Path("/")
- public List<Metadata> getJsonSchemaExtensionsMetadatas(@QueryParam("offset") @DefaultValue("0") int offset,
- @QueryParam("size") @DefaultValue("50") int size, @QueryParam("sort") String sortBy) {
- return schemaService.getJsonSchemaExtensionsMetadatas(offset, size, sortBy).getList();
- }
-
- /**
- * Save a JSON schema extension
- *
- * @param jsonSchemaExtension the schema as string to save
- * @return Response of the API call
- */
- @POST
- @Path("/")
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.APPLICATION_JSON)
- public Response save(String jsonSchemaExtension) throws IOException {
- schemaService.saveExtension(jsonSchemaExtension);
- return Response.ok().build();
- }
-
- /**
- * Deletes a JSON schema extension.
- * The id is a Base64 id as the id have is basically an URL
- *
- * @param id the identifier of the JSON schema that we want to delete
- */
- @DELETE
- @Path("/{id}")
- public void remove(@PathParam("id") String id) {
- schemaService.deleteExtension(id);
- }
-}
diff --git a/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java b/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java
index 0da55b996..f2b85feb7 100644
--- a/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java
+++ b/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java
@@ -30,7 +30,6 @@ import org.apache.cxf.message.Message;
import org.apache.unomi.api.ContextRequest;
import org.apache.unomi.api.EventsCollectorRequest;
import org.apache.unomi.api.services.ConfigSharingService;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.rest.authentication.AuthenticationFilter;
import org.apache.unomi.rest.authentication.AuthorizingInterceptor;
import org.apache.unomi.rest.authentication.RestAuthenticationConfig;
@@ -38,6 +37,7 @@ import org.apache.unomi.rest.deserializers.ContextRequestDeserializer;
import org.apache.unomi.rest.deserializers.EventsCollectorRequestDeserializer;
import org.apache.unomi.rest.server.provider.RetroCompatibilityParamConverterProvider;
import org.apache.unomi.rest.validation.request.RequestValidatorInterceptor;
+import org.apache.unomi.schema.api.SchemaService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
diff --git a/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java b/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java
index 4600f0c1e..ac617d3d7 100644
--- a/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java
+++ b/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java
@@ -17,7 +17,6 @@
package org.apache.unomi.rest.service.impl;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.unomi.api.Event;
import org.apache.unomi.api.Persona;
import org.apache.unomi.api.Profile;
@@ -25,9 +24,9 @@ import org.apache.unomi.api.Session;
import org.apache.unomi.api.services.ConfigSharingService;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.PrivacyService;
-import org.apache.unomi.api.services.SchemaService;
import org.apache.unomi.rest.exception.InvalidRequestException;
import org.apache.unomi.rest.service.RestServiceUtils;
+import org.apache.unomi.schema.api.SchemaService;
import org.apache.unomi.utils.Changes;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -38,7 +37,6 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.BadRequestException;
import java.util.Date;
import java.util.List;
@@ -56,7 +54,8 @@ public class RestServiceUtilsImpl implements RestServiceUtils {
@Reference
private EventService eventService;
- @Reference SchemaService schemaService;
+ @Reference
+ SchemaService schemaService;
public String getProfileIdCookieValue(HttpServletRequest httpServletRequest) {
String cookieProfileId = null;
@@ -67,7 +66,7 @@ public class RestServiceUtilsImpl implements RestServiceUtils {
for (Cookie cookie : cookies) {
final Object profileIdCookieName = configSharingService.getProperty("profileIdCookieName");
if (profileIdCookieName.equals(cookie.getName())) {
- if (!schemaService.isValid(JsonNodeFactory.instance.objectNode().put("profileIdCookieName", cookie.getValue()), "https://unomi.apache.org/schemas/json/cookie/1-0-0")) {
+ if (!schemaService.isValid(JsonNodeFactory.instance.objectNode().put("profileIdCookieName", cookie.getValue()).toString(), "https://unomi.apache.org/schemas/json/cookie/1-0-0")) {
throw new InvalidRequestException("Invalid profile ID format in cookie", "Invalid received data");
}
cookieProfileId = cookie.getValue();
diff --git a/services/src/main/resources/META-INF/cxs/schemas/contextrequest.json b/rest/src/main/resources/META-INF/cxs/schemas/contextrequest.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/contextrequest.json
rename to rest/src/main/resources/META-INF/cxs/schemas/contextrequest.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json b/rest/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json
rename to rest/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/cookie.json b/rest/src/main/resources/META-INF/cxs/schemas/cookie.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/cookie.json
rename to rest/src/main/resources/META-INF/cxs/schemas/cookie.json
diff --git a/services/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json b/rest/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json
similarity index 100%
rename from services/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json
rename to rest/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json
diff --git a/services/pom.xml b/services/pom.xml
index c4acbb2f5..3f41968ee 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -171,13 +171,6 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
-
- <dependency>
- <groupId>com.networknt</groupId>
- <artifactId>json-schema-validator</artifactId>
- <version>1.0.49</version>
- </dependency>
-
</dependencies>
<build>
@@ -191,10 +184,6 @@
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Import-Package>
sun.misc;resolution:=optional,
- org.jcodings;resolution:=optional,
- org.jcodings.specific;resolution:=optional,
- org.joni;resolution:=optional,
- org.joni.exception;resolution:=optional,
*
</Import-Package>
</instructions>
diff --git a/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java
index 736de11cb..5b81819b9 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java
@@ -65,8 +65,6 @@ public class EventServiceImpl implements EventService {
private BundleContext bundleContext;
- private SchemaService schemaService;
-
private Set<String> predefinedEventTypeIds = new LinkedHashSet<String>();
private Set<String> restrictedEventTypeIds = new LinkedHashSet<String>();
@@ -114,9 +112,6 @@ public class EventServiceImpl implements EventService {
this.shouldBeCheckedEventSourceId = shouldBeCheckedEventSourceId;
}
- public void setSchemaService(SchemaService schemaService) {
- this.schemaService = schemaService;
- }
public void setPersistenceService(PersistenceService persistenceService) {
this.persistenceService = persistenceService;
}
diff --git a/services/src/main/java/org/apache/unomi/services/impl/schemas/SchemaServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/schemas/SchemaServiceImpl.java
deleted file mode 100644
index 56d70f29c..000000000
--- a/services/src/main/java/org/apache/unomi/services/impl/schemas/SchemaServiceImpl.java
+++ /dev/null
@@ -1,339 +0,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.
- */
-
-package org.apache.unomi.services.impl.schemas;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.networknt.schema.JsonMetaSchema;
-import com.networknt.schema.JsonSchema;
-import com.networknt.schema.JsonSchemaFactory;
-import com.networknt.schema.NonValidationKeyword;
-import com.networknt.schema.SpecVersion;
-import com.networknt.schema.ValidationMessage;
-import com.networknt.schema.uri.URIFetcher;
-import org.apache.commons.io.IOUtils;
-import org.apache.unomi.api.Metadata;
-import org.apache.unomi.api.PartialList;
-import org.apache.unomi.api.schema.JSONSchemaExtension;
-import org.apache.unomi.api.schema.UnomiJSONSchema;
-import org.apache.unomi.api.schema.json.JSONSchema;
-import org.apache.unomi.api.schema.json.JSONTypeFactory;
-import org.apache.unomi.api.services.ProfileService;
-import org.apache.unomi.api.services.SchedulerService;
-import org.apache.unomi.api.services.SchemaService;
-import org.apache.unomi.persistence.spi.CustomObjectMapper;
-import org.apache.unomi.persistence.spi.PersistenceService;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TimerTask;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-public class SchemaServiceImpl implements SchemaService {
-
- private static final String URI = "https://json-schema.org/draft/2019-09/schema";
-
- private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class.getName());
-
- private final Map<String, JSONSchema> predefinedUnomiJSONSchemaById = new HashMap<>();
-
- private Map<String, JSONSchema> schemasById = new HashMap<>();
-
- private Map<String, JSONSchemaExtension> extensionById = new HashMap<>();
-
- private BundleContext bundleContext;
-
- private ProfileService profileService;
-
- private PersistenceService persistenceService;
-
- private SchedulerService schedulerService;
-
- private JsonSchemaFactory jsonSchemaFactory;
-
- ObjectMapper objectMapper = new ObjectMapper();
-
- private ScheduledFuture<?> scheduledFuture;
-
- private Integer jsonSchemaRefreshInterval = 1000;
-
- public void setPersistenceService(PersistenceService persistenceService) {
- this.persistenceService = persistenceService;
- }
-
- public void setSchedulerService(SchedulerService schedulerService) {
- this.schedulerService = schedulerService;
- }
-
- public void setJsonSchemaRefreshInterval(Integer jsonSchemaRefreshInterval) {
- this.jsonSchemaRefreshInterval = jsonSchemaRefreshInterval;
- }
-
- @Override
- public PartialList<Metadata> getJsonSchemaMetadatas(int offset, int size, String sortBy) {
- PartialList<UnomiJSONSchema> items = persistenceService.getAllItems(UnomiJSONSchema.class, offset, size, sortBy);
- List<Metadata> details = new LinkedList<>();
- for (UnomiJSONSchema definition : items.getList()) {
- details.add(definition.getMetadata());
- }
- return new PartialList<>(details, items.getOffset(), items.getPageSize(), items.getTotalSize(), items.getTotalSizeRelation());
- }
-
- @Override
- public boolean isValid(JsonNode jsonNode, String schemaId) {
- String schemaAsString;
- JsonSchema jsonSchema = null;
- try {
- JSONSchema validationSchema = schemasById.get(schemaId);
- if (validationSchema != null) {
- schemaAsString = objectMapper.writeValueAsString(schemasById.get(schemaId).getSchemaTree());
- jsonSchema = jsonSchemaFactory.getSchema(schemaAsString);
- } else {
- logger.warn("No schema found for {}", schemaId);
- }
- } catch (JsonProcessingException e) {
- logger.error("Failed to process json schema", e);
- }
-
- if (jsonSchema != null) {
-
- Set<ValidationMessage> validationMessages = jsonSchema.validate(jsonNode);
- if (validationMessages == null || validationMessages.isEmpty()) {
- return true;
- }
- for (ValidationMessage validationMessage : validationMessages) {
- logger.error("Error validating object against schema {}: {}", schemaId, validationMessage);
- }
- return false;
- }
- return false;
- }
-
- @Override
- public List<JSONSchema> getSchemasByTarget(String target) {
- return schemasById.values().stream().filter(jsonSchema -> jsonSchema.getTarget() != null && jsonSchema.getTarget().equals(target))
- .collect(Collectors.toList());
-
- }
-
- @Override
- public void saveSchema(String schema) {
- JsonSchema jsonSchema = jsonSchemaFactory.getSchema(schema);
- if (jsonSchema.getSchemaNode().at("/self/target").asText().equals("events") && !jsonSchema.getSchemaNode().at("/self/name").asText()
- .matches("[_A-Za-z][_0-9A-Za-z]*")) {
- throw new IllegalArgumentException(
- "The \"/self/name\" value should match the following regular expression [_A-Za-z][_0-9A-Za-z]* for the Json schema on"
- + " events");
- }
- if (predefinedUnomiJSONSchemaById.get(jsonSchema.getSchemaNode().get("$id").asText()) == null) {
- persistenceService.save(buildUnomiJsonSchema(schema));
- JSONSchema localSchema = buildJSONSchema(jsonSchema);
- schemasById.put(jsonSchema.getSchemaNode().get("$id").asText(), localSchema);
- } else {
- logger.error("Can not store a JSON Schema which have the id of a schema preovided by Unomi");
- }
- }
-
- @Override
- public void saveSchema(InputStream schemaStream) throws IOException {
- saveSchema(IOUtils.toString(schemaStream));
- }
-
- @Override
- public void loadPredefinedSchema(InputStream schemaStream) {
- JsonSchema jsonSchema = jsonSchemaFactory.getSchema(schemaStream);
- JSONSchema localJsonSchema = buildJSONSchema(jsonSchema);
-
- predefinedUnomiJSONSchemaById.put(jsonSchema.getSchemaNode().get("$id").asText(), localJsonSchema);
- schemasById.put(jsonSchema.getSchemaNode().get("$id").asText(), localJsonSchema);
- }
-
- @Override
- public boolean deleteSchema(String schemaId) {
- schemasById.remove(schemaId);
- return persistenceService.remove(schemaId, UnomiJSONSchema.class);
- }
-
- @Override
- public boolean deleteSchema(InputStream schemaStream) {
- JsonNode schemaNode = jsonSchemaFactory.getSchema(schemaStream).getSchemaNode();
- return deleteSchema(schemaNode.get("$id").asText());
- }
-
- @Override
- public void saveExtension(InputStream extensionStream) throws IOException {
- saveExtension(IOUtils.toString(extensionStream));
- }
-
- @Override
- public void saveExtension(String extension) throws IOException {
- JSONSchemaExtension jsonSchemaExtension = buildExtension(extension);
- persistenceService.save(jsonSchemaExtension);
- extensionById.put(jsonSchemaExtension.getId(), jsonSchemaExtension);
- }
-
- @Override
- public boolean deleteExtension(InputStream extensionStream) throws IOException {
- JsonNode jsonNode = objectMapper.readTree(extensionStream);
- return deleteExtension(jsonNode.get("id").asText());
- }
-
- @Override
- public boolean deleteExtension(String extensionId) {
- extensionById.remove(extensionId);
- return persistenceService.remove(extensionId, JSONSchemaExtension.class);
- }
-
- @Override
- public PartialList<Metadata> getJsonSchemaExtensionsMetadatas(int offset, int size, String sortBy) {
- PartialList<JSONSchemaExtension> items = persistenceService.getAllItems(JSONSchemaExtension.class, offset, size, sortBy);
- List<Metadata> details = new LinkedList<>();
- for (JSONSchemaExtension definition : items.getList()) {
- details.add(definition.getMetadata());
- }
- return new PartialList<>(details, items.getOffset(), items.getPageSize(), items.getTotalSize(), items.getTotalSizeRelation());
- }
-
- private JSONSchemaExtension buildExtension(String extension) throws JsonProcessingException {
- JsonNode jsonNode = objectMapper.readTree(extension);
- JSONSchemaExtension jsonSchemaExtension = new JSONSchemaExtension();
- jsonSchemaExtension.setId(jsonNode.get("id").asText());
- jsonSchemaExtension.setSchemaId(jsonNode.get("schemaId").asText());
- jsonSchemaExtension.setExtension(jsonNode.get("extension").toString());
- jsonSchemaExtension.setPriority(jsonNode.get("priority").asDouble());
- Metadata metadata = new Metadata();
- metadata.setId(jsonNode.get("id").asText());
- metadata.setDescription(jsonNode.get("description").asText());
- metadata.setName(jsonNode.get("name").asText());
- jsonSchemaExtension.setMetadata(metadata);
- return jsonSchemaExtension;
- }
-
- @Override
- public JSONSchema getSchema(String schemaId) {
- return schemasById.get(schemaId);
- }
-
- private JSONSchema buildJSONSchema(JsonSchema jsonSchema) {
- return Optional.of(jsonSchema).map(jsonSchemaToProcess -> {
- try {
- return (Map<String, Object>) objectMapper.treeToValue(jsonSchemaToProcess.getSchemaNode(), Map.class);
- } catch (JsonProcessingException e) {
- logger.error("Failed to process Json object, e");
- }
- return Collections.<String, Object>emptyMap();
- }).map(jsonSchemaToProcess -> {
- JSONSchema schema = new JSONSchema(jsonSchemaToProcess, new JSONTypeFactory(this));
- schema.setPluginId(bundleContext.getBundle().getBundleId());
- return schema;
- }).get();
- }
-
- private UnomiJSONSchema buildUnomiJsonSchema(String schema) {
- JsonNode schemaNode = jsonSchemaFactory.getSchema(schema).getSchemaNode();
- return new UnomiJSONSchema(schemaNode.get("$id").asText(), schema, schemaNode.at("/self/target").asText());
- }
-
- public JsonSchema getJsonSchema(String schemaId) {
- String schemaAsString = null;
- try {
- schemaAsString = objectMapper.writeValueAsString(schemasById.get(schemaId).getSchemaTree());
- } catch (JsonProcessingException e) {
- logger.error("Failed to process json schema", e);
- }
- return jsonSchemaFactory.getSchema(schemaAsString);
- }
-
- private URIFetcher getUriFetcher() {
- return uri -> {
- logger.debug("Fetching schema {}", uri);
- String schemaAsString = null;
- try {
- schemaAsString = objectMapper.writeValueAsString(schemasById.get(uri.toString()).getSchemaTree());
- } catch (JsonProcessingException e) {
- logger.error("Failed to process json schema", e);
- }
- JsonSchema schema = jsonSchemaFactory.getSchema(schemaAsString);
- if (schema == null) {
- logger.error("Couldn't find schema {}", uri);
- return null;
- }
- return IOUtils.toInputStream(schema.getSchemaNode().asText());
- };
- }
-
- private void refreshJSONSchemas() {
- schemasById = new HashMap<>();
- schemasById.putAll(predefinedUnomiJSONSchemaById);
- persistenceService.getAllItems(UnomiJSONSchema.class).forEach(
- jsonSchema -> schemasById.put(jsonSchema.getId(), buildJSONSchema(jsonSchemaFactory.getSchema(jsonSchema.getSchema()))));
- }
-
- private void refreshJSONSchemasExtensions() {
- extensionById = new HashMap<>();
- persistenceService.getAllItems(JSONSchemaExtension.class).forEach(extension -> extensionById.put(extension.getId(), extension));
- }
-
- private void initializeTimers() {
- TimerTask task = new TimerTask() {
- @Override
- public void run() {
- refreshJSONSchemas();
- refreshJSONSchemasExtensions();
- }
- };
- scheduledFuture = schedulerService.getScheduleExecutorService()
- .scheduleWithFixedDelay(task, 0, jsonSchemaRefreshInterval, TimeUnit.MILLISECONDS);
- }
-
- public void init() {
- JsonMetaSchema jsonMetaSchema = JsonMetaSchema.builder(URI, JsonMetaSchema.getV201909())
- .addKeyword(new UnomiPropertyTypeKeyword(profileService, this)).addKeyword(new NonValidationKeyword("self")).build();
- jsonSchemaFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909))
- .addMetaSchema(jsonMetaSchema).defaultMetaSchemaURI(URI).uriFetcher(getUriFetcher(), "https", "http").build();
-
- initializeTimers();
- logger.info("Schema service initialized.");
- }
-
- public void destroy() {
- scheduledFuture.cancel(true);
- logger.info("Schema service shutdown.");
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void setProfileService(ProfileService profileService) {
- this.profileService = profileService;
- }
-}
diff --git a/services/src/main/java/org/apache/unomi/services/impl/schemas/UnomiPropertyTypeKeyword.java b/services/src/main/java/org/apache/unomi/services/impl/schemas/UnomiPropertyTypeKeyword.java
deleted file mode 100644
index 973d4acf0..000000000
--- a/services/src/main/java/org/apache/unomi/services/impl/schemas/UnomiPropertyTypeKeyword.java
+++ /dev/null
@@ -1,126 +0,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.
- */
-package org.apache.unomi.services.impl.schemas;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.networknt.schema.AbstractJsonValidator;
-import com.networknt.schema.AbstractKeyword;
-import com.networknt.schema.CustomErrorMessageType;
-import com.networknt.schema.JsonSchema;
-import com.networknt.schema.JsonSchemaException;
-import com.networknt.schema.JsonValidator;
-import com.networknt.schema.ValidationContext;
-import com.networknt.schema.ValidationMessage;
-import org.apache.unomi.api.PropertyType;
-import org.apache.unomi.api.services.ProfileService;
-import org.apache.unomi.api.services.SchemaService;
-
-import java.text.MessageFormat;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-class UnomiPropertyTypeKeyword extends AbstractKeyword {
-
- private final ProfileService profileService;
- private final SchemaServiceImpl schemaService;
-
- private static final class UnomiPropertyTypeJsonValidator extends AbstractJsonValidator {
-
- String schemaPath;
- JsonNode schemaNode;
- JsonSchema parentSchema;
- ValidationContext validationContext;
- ProfileService profileService;
- SchemaServiceImpl schemaService;
-
- public UnomiPropertyTypeJsonValidator(String keyword, String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
- ValidationContext validationContext, ProfileService profileService, SchemaServiceImpl schemaService) {
- super(keyword);
- this.schemaPath = schemaPath;
- this.schemaNode = schemaNode;
- this.parentSchema = parentSchema;
- this.validationContext = validationContext;
- this.profileService = profileService;
- this.schemaService = schemaService;
- }
-
- @Override
- public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
- Set<ValidationMessage> validationMessages = new HashSet<>();
- Iterator<String> fieldNames = node.fieldNames();
- while (fieldNames.hasNext()) {
- String fieldName = fieldNames.next();
- PropertyType propertyType = getPropertyType(fieldName);
- if (propertyType == null) {
- validationMessages.add(buildValidationMessage(CustomErrorMessageType
- .of("property-not-found", new MessageFormat("{0} : Couldn''t find property type with id={1}")), at, fieldName));
- } else {
- // @todo further validation, if it can be used in this context (event, profile, session)
- String valueTypeId = propertyType.getValueTypeId();
- JsonSchema jsonSchema = schemaService
- .getJsonSchema("https://unomi.apache.org/schemas/json/values/" + valueTypeId + ".json");
- if (jsonSchema == null) {
- validationMessages.add(buildValidationMessage(CustomErrorMessageType
- .of("value-schema-not-found", new MessageFormat("{0} : Couldn''t find schema type with id={1}")), at,
- "https://unomi.apache.org/schemas/json/values/" + valueTypeId + ".json"));
- } else {
- Set<ValidationMessage> propertyValidationMessages = jsonSchema.validate(node.get(fieldName));
- if (propertyValidationMessages != null) {
- validationMessages.addAll(propertyValidationMessages);
- }
- }
- }
- }
- return validationMessages;
- }
-
- private PropertyType getPropertyType(String fieldName) {
- Map<String, PropertyType> propertyTypes = new HashMap<>();
- if (schemaNode.size() > 0) {
- for (Iterator<JsonNode> it = schemaNode.iterator(); it.hasNext(); ) {
- JsonNode target = it.next();
- if ("_all".equals(target.asText())) {
- return profileService.getPropertyType(fieldName);
- } else {
- Collection<PropertyType> targetPropertyTypes = profileService.getTargetPropertyTypes(target.asText());
- targetPropertyTypes.stream().map(propertyType -> propertyTypes.put(propertyType.getItemId(), propertyType));
- }
- }
- return propertyTypes.get(fieldName);
- } else {
- return profileService.getPropertyType(fieldName);
- }
- }
- }
-
- public UnomiPropertyTypeKeyword(ProfileService profileService, SchemaServiceImpl schemaService) {
- super("unomiPropertyTypes");
- this.profileService = profileService;
- this.schemaService = schemaService;
- }
-
- @Override
- public JsonValidator newValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext)
- throws JsonSchemaException, Exception {
- return new UnomiPropertyTypeJsonValidator(this.getValue(), schemaPath, schemaNode, parentSchema, validationContext, profileService,
- schemaService);
- }
-}
diff --git a/services/src/main/java/org/apache/unomi/services/listener/JsonSchemaListener.java b/services/src/main/java/org/apache/unomi/services/listener/JsonSchemaListener.java
deleted file mode 100644
index 21dab227f..000000000
--- a/services/src/main/java/org/apache/unomi/services/listener/JsonSchemaListener.java
+++ /dev/null
@@ -1,217 +0,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.
- */
-package org.apache.unomi.services.listener;
-
-import org.apache.unomi.api.schema.JSONSchemaExtension;
-import org.apache.unomi.api.schema.UnomiJSONSchema;
-import org.apache.unomi.api.services.SchemaService;
-import org.apache.unomi.persistence.spi.PersistenceService;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.SynchronousBundleListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Enumeration;
-
-/**
- * An implementation of a BundleListener for the JSON schema.
- * It will load the pre-defined schema files in the folder META-INF/cxs/schemas.
- * It will load the extension of schema in the folder META-INF/cxs/schemasextensions.
- * The scripts will be stored in the ES index jsonSchema and the extension will be stored in jsonSchemaExtension
- */
-public class JsonSchemaListener implements SynchronousBundleListener {
-
- private static final Logger logger = LoggerFactory.getLogger(JsonSchemaListener.class.getName());
- public static final String ENTRIES_LOCATION = "META-INF/cxs/schemas";
-
- public static final String EXTENSIONS_ENTRIES_LOCATION = "META-INF/cxs/schemasextensions";
-
- private PersistenceService persistenceService;
-
- private SchemaService schemaService;
-
- private BundleContext bundleContext;
-
- public void setPersistenceService(PersistenceService persistenceService) {
- this.persistenceService = persistenceService;
- }
-
- public void setSchemaService(SchemaService schemaService) {
- this.schemaService = schemaService;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void postConstruct() {
- logger.info("JSON schema listener initializing...");
- logger.debug("postConstruct {}", bundleContext.getBundle());
- createIndexes();
-
- loadPredefinedSchemas(bundleContext);
-
- for (Bundle bundle : bundleContext.getBundles()) {
- if (bundle.getBundleContext() != null && bundle.getBundleId() != bundleContext.getBundle().getBundleId()) {
- saveSchemas(bundle.getBundleContext());
- saveExtensions(bundle.getBundleContext());
- }
- }
-
- bundleContext.addBundleListener(this);
- logger.info("JSON schema listener initialized.");
- }
-
- public void preDestroy() {
- bundleContext.removeBundleListener(this);
- logger.info("JSON schema listener shutdown.");
- }
-
- private void processBundleStartup(BundleContext bundleContext) {
- if (bundleContext == null) {
- return;
- }
- saveSchemas(bundleContext);
- }
-
- private void processBundleStop(BundleContext bundleContext) {
- if (bundleContext == null) {
- return;
- }
- unloadSchemas(bundleContext);
- unloadExtensions(bundleContext);
- }
-
- public void bundleChanged(BundleEvent event) {
- switch (event.getType()) {
- case BundleEvent.STARTED:
- processBundleStartup(event.getBundle().getBundleContext());
- break;
- case BundleEvent.STOPPING:
- if (!event.getBundle().getSymbolicName().equals(bundleContext.getBundle().getSymbolicName())) {
- processBundleStop(event.getBundle().getBundleContext());
- }
- break;
- }
- }
-
- public void createIndexes() {
- if (persistenceService.createIndex(UnomiJSONSchema.ITEM_TYPE)) {
- logger.info("{} index created", UnomiJSONSchema.ITEM_TYPE);
- } else {
- logger.info("{} index already exists", UnomiJSONSchema.ITEM_TYPE);
- }
- if (persistenceService.createIndex(JSONSchemaExtension.ITEM_TYPE)) {
- logger.info("{} index created", JSONSchemaExtension.ITEM_TYPE);
- } else {
- logger.info("{} index already exists", JSONSchemaExtension.ITEM_TYPE);
- }
- }
-
- private void saveSchemas(BundleContext bundleContext) {
- Enumeration<URL> predefinedSchemas = bundleContext.getBundle().findEntries(ENTRIES_LOCATION, "*.json", true);
- if (predefinedSchemas == null) {
- return;
- }
-
- while (predefinedSchemas.hasMoreElements()) {
- URL predefinedSchemaURL = predefinedSchemas.nextElement();
- logger.debug("Found JSON schema at {}, loading... ", predefinedSchemaURL);
-
- try (InputStream schemaInputStream = predefinedSchemaURL.openStream()) {
- schemaService.saveSchema(schemaInputStream);
- } catch (Exception e) {
- logger.error("Error while loading schema definition {}", predefinedSchemaURL, e);
- }
- }
- }
-
- private void loadPredefinedSchemas(BundleContext bundleContext) {
- Enumeration<URL> predefinedSchemas = bundleContext.getBundle().findEntries(ENTRIES_LOCATION, "*.json", true);
- if (predefinedSchemas == null) {
- return;
- }
-
- while (predefinedSchemas.hasMoreElements()) {
- URL predefinedSchemaURL = predefinedSchemas.nextElement();
- logger.debug("Found predefined JSON schema at {}, loading... ", predefinedSchemaURL);
- try (InputStream schemaInputStream = predefinedSchemaURL.openStream()) {
- schemaService.loadPredefinedSchema(schemaInputStream);
- } catch (Exception e) {
- logger.error("Error while loading schema definition {}", predefinedSchemaURL, e);
- }
- }
- }
-
- private void unloadSchemas(BundleContext bundleContext) {
- Enumeration<URL> predefinedSchemas = bundleContext.getBundle().findEntries(ENTRIES_LOCATION, "*.json", true);
- if (predefinedSchemas == null) {
- return;
- }
-
- while (predefinedSchemas.hasMoreElements()) {
- URL predefinedSchemaURL = predefinedSchemas.nextElement();
- logger.debug("Found predefined JSON schema at {}, loading... ", predefinedSchemaURL);
-
- try (InputStream schemaInputStream = predefinedSchemaURL.openStream()) {
- schemaService.deleteSchema(schemaInputStream);
- } catch (Exception e) {
- logger.error("Error while removing schema at {}", predefinedSchemaURL, e);
- }
- }
- }
-
- private void saveExtensions(BundleContext bundleContext) {
- Enumeration<URL> extensions = bundleContext.getBundle().findEntries(EXTENSIONS_ENTRIES_LOCATION, "*.json", true);
- if (extensions == null) {
- return;
- }
-
- while (extensions.hasMoreElements()) {
- URL extensionURL = extensions.nextElement();
- logger.debug("Found JSON schema extension at {}, loading... ", extensionURL);
-
- try (InputStream extensionInputStream = extensionURL.openStream()) {
- schemaService.saveExtension(extensionInputStream);
- } catch (Exception e) {
- logger.error("Error while loading schema extension at {}", extensionURL, e);
- }
- }
- }
-
- private void unloadExtensions(BundleContext bundleContext) {
- Enumeration<URL> extensions = bundleContext.getBundle().findEntries(EXTENSIONS_ENTRIES_LOCATION, "*.json", true);
- if (extensions == null) {
- return;
- }
-
- while (extensions.hasMoreElements()) {
- URL predefinedSchemaURL = extensions.nextElement();
- logger.debug("Found JSON schema extension at {}, loading... ", predefinedSchemaURL);
-
- try (InputStream extensionInputStream = predefinedSchemaURL.openStream()) {
- schemaService.deleteExtension(extensionInputStream);
- } catch (Exception e) {
- logger.error("Error while loading schema extension at {}", predefinedSchemaURL, e);
- }
- }
- }
-}
diff --git a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 1d1417c12..68ce68e9f 100644
--- a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -45,7 +45,6 @@
<cm:property name="events.shouldBeCheckedEventSourceId" value="false"/>
<cm:property name="rules.optimizationActivated" value="true"/>
<cm:property name="schedules.thread.poolSize" value="5"/>
- <cm:property name="json.schema.refresh.interval" value="1000"/>
</cm:default-properties>
</cm:property-placeholder>
@@ -102,34 +101,11 @@
</interfaces>
</service>
- <bean id="schemaServiceImpl" class="org.apache.unomi.services.impl.schemas.SchemaServiceImpl" init-method="init"
- destroy-method="destroy">
- <property name="bundleContext" ref="blueprintBundleContext"/>
- <property name="profileService" ref="profileServiceImpl"/>
- <property name="persistenceService" ref="persistenceService"/>
- <property name="schedulerService" ref="schedulerServiceImpl"/>
- <property name="jsonSchemaRefreshInterval" value="${services.json.schema.refresh.interval}"/>
- </bean>
- <service id="schemaService" ref="schemaServiceImpl" interface="org.apache.unomi.api.services.SchemaService"/>
-
- <bean id="jsonSchemaListenerImpl" class="org.apache.unomi.services.listener.JsonSchemaListener"
- init-method="postConstruct" destroy-method="preDestroy">
- <property name="persistenceService" ref="persistenceService"/>
- <property name="bundleContext" ref="blueprintBundleContext"/>
- <property name="schemaService" ref="schemaServiceImpl"/>
- </bean>
- <service id="jsonSchemaListener" ref="jsonSchemaListenerImpl">
- <interfaces>
- <value>org.osgi.framework.SynchronousBundleListener</value>
- </interfaces>
- </service>
-
<bean id="eventServiceImpl" class="org.apache.unomi.services.impl.events.EventServiceImpl">
<property name="persistenceService" ref="persistenceService"/>
<property name="definitionsService" ref="definitionsServiceImpl"/>
<property name="sourceService" ref="sourceServiceImpl"/>
<property name="bundleContext" ref="blueprintBundleContext"/>
- <property name="schemaService" ref="schemaServiceImpl"/>
<property name="predefinedEventTypeIds">
<set>
<value>view</value>
diff --git a/services/src/main/resources/org.apache.unomi.services.cfg b/services/src/main/resources/org.apache.unomi.services.cfg
index 1f9a9bd6a..452b7591b 100644
--- a/services/src/main/resources/org.apache.unomi.services.cfg
+++ b/services/src/main/resources/org.apache.unomi.services.cfg
@@ -77,6 +77,3 @@ rules.optimizationActivated=${org.apache.unomi.rules.optimizationActivated:-true
# The number of threads to compose the pool size of the scheduler.
scheduler.thread.poolSize=${org.apache.unomi.scheduler.thread.poolSize:-5}
-
-# The interval in milliseconds to reload the json schemas in memory
-services.json.schema.refresh.interval=${org.apache.unomi.json.schema.refresh.interval:-1000}
diff --git a/tools/shell-commands/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/tools/shell-commands/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index a6223d592..3e0ab6974 100644
--- a/tools/shell-commands/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/tools/shell-commands/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -44,6 +44,8 @@
<value>org.apache.unomi.cxs-geonames-rest</value>
<value>org.apache.unomi.cxs-privacy-extension-services</value>
<value>org.apache.unomi.cxs-privacy-extension-rest</value>
+ <value>org.apache.unomi.json-schema-services</value>
+ <value>org.apache.unomi.json-schema-rest</value>
<value>org.apache.unomi.rest</value>
<value>org.apache.unomi.wab</value>
<value>org.apache.unomi.plugins-base</value>