You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by sh...@apache.org on 2022/03/11 09:56:10 UTC
[unomi] branch master updated: UNOMI-554 Improve server identification & various bug fixes (#392)
This is an automated email from the ASF dual-hosted git repository.
shuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/unomi.git
The following commit(s) were added to refs/heads/master by this push:
new 0cf8420 UNOMI-554 Improve server identification & various bug fixes (#392)
0cf8420 is described below
commit 0cf8420e75db1998a6ef02ca67983584f18e4c29
Author: Serge Huber <sh...@jahia.com>
AuthorDate: Fri Mar 11 10:56:06 2022 +0100
UNOMI-554 Improve server identification & various bug fixes (#392)
- Add /cxs/privacy/infos endpoint to retrieve all server information
- Make it possible to override server information and extend it
- Add build number, build date, build timestamp and scm branch reporting
- Add possibility to override startup logo
- Refactor BundleWatcher
- Fix negative test event type bug.
- Fix bug in GraphQL JSON schema integration
---
.../main/java/org/apache/unomi/api/ServerInfo.java | 48 ++++
.../apache/unomi/api/services/PrivacyService.java | 14 +-
.../unomi/privacy/rest/PrivacyServiceEndPoint.java | 6 +
extensions/privacy-extension/services/pom.xml | 6 +
.../unomi/privacy/internal/PrivacyServiceImpl.java | 23 +-
.../resources/OSGI-INF/blueprint/blueprint.xml | 3 +
.../types/resolvers/CDPEventInterfaceResolver.java | 2 +-
.../test/java/org/apache/unomi/itests/AllITs.java | 1 +
.../test/java/org/apache/unomi/itests/BaseIT.java | 198 +++++++++++++++
.../org/apache/unomi/itests/PrivacyServiceIT.java | 81 ++++++
.../schemas/events/negative-test-event-type.json | 13 +
lifecycle-watcher/pom.xml | 8 +
.../org/apache/unomi/lifecycle/BundleWatcher.java | 276 +--------------------
.../{BundleWatcher.java => BundleWatcherImpl.java} | 118 +++++++--
.../resources/OSGI-INF/blueprint/blueprint.xml | 4 +-
.../main/resources/{logo.txt => unomi-logo.txt} | 2 -
.../impl/schemas/UnomiPropertyTypeKeyword.java | 6 +-
.../META-INF/cxs/schemas/events/view.json | 1 -
18 files changed, 504 insertions(+), 306 deletions(-)
diff --git a/api/src/main/java/org/apache/unomi/api/ServerInfo.java b/api/src/main/java/org/apache/unomi/api/ServerInfo.java
index 2006a1f..7b80f94 100644
--- a/api/src/main/java/org/apache/unomi/api/ServerInfo.java
+++ b/api/src/main/java/org/apache/unomi/api/ServerInfo.java
@@ -17,6 +17,8 @@
package org.apache.unomi.api;
+import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -27,10 +29,16 @@ public class ServerInfo {
private String serverIdentifier;
private String serverVersion;
+ private String serverBuildNumber;
+ private Date serverBuildDate;
+ private String serverTimestamp;
+ private String serverScmBranch;
private List<EventInfo> eventTypes;
private Map<String,String> capabilities;
+ private List<String> logoLines = new ArrayList<>();
+
public ServerInfo() {
}
@@ -50,6 +58,38 @@ public class ServerInfo {
this.serverVersion = serverVersion;
}
+ public String getServerBuildNumber() {
+ return serverBuildNumber;
+ }
+
+ public void setServerBuildNumber(String serverBuildNumber) {
+ this.serverBuildNumber = serverBuildNumber;
+ }
+
+ public Date getServerBuildDate() {
+ return serverBuildDate;
+ }
+
+ public void setServerBuildDate(Date serverBuildDate) {
+ this.serverBuildDate = serverBuildDate;
+ }
+
+ public String getServerTimestamp() {
+ return serverTimestamp;
+ }
+
+ public void setServerTimestamp(String serverTimestamp) {
+ this.serverTimestamp = serverTimestamp;
+ }
+
+ public String getServerScmBranch() {
+ return serverScmBranch;
+ }
+
+ public void setServerScmBranch(String serverScmBranch) {
+ this.serverScmBranch = serverScmBranch;
+ }
+
public List<EventInfo> getEventTypes() {
return eventTypes;
}
@@ -65,4 +105,12 @@ public class ServerInfo {
public void setCapabilities(Map<String, String> capabilities) {
this.capabilities = capabilities;
}
+
+ public List<String> getLogoLines() {
+ return logoLines;
+ }
+
+ public void setLogoLines(List<String> logoLines) {
+ this.logoLines = logoLines;
+ }
}
diff --git a/api/src/main/java/org/apache/unomi/api/services/PrivacyService.java b/api/src/main/java/org/apache/unomi/api/services/PrivacyService.java
index 35f11be..3f7d555 100644
--- a/api/src/main/java/org/apache/unomi/api/services/PrivacyService.java
+++ b/api/src/main/java/org/apache/unomi/api/services/PrivacyService.java
@@ -28,13 +28,23 @@ import java.util.List;
public interface PrivacyService {
/**
- * Retrieves the server information, including the name and version of the server, the event types
- * if recognizes as well as the capabilities supported by the system.
+ * Retrieves the default base Apache Unomi server information, including the name and version of the server, build
+ * time information and the event types
+ * if recognizes as well as the capabilities supported by the system. For more detailed information about the system
+ * and extensions use the getServerInfos method.
* @return a ServerInfo object with all the server information
*/
ServerInfo getServerInfo();
/**
+ * Retrieves the list of the server information objects, that include extensions. Each object includes the
+ * name and version of the server, build time information and the event types
+ * if recognizes as well as the capabilities supported by the system.
+ * @return a list of ServerInfo objects with all the server information
+ */
+ List<ServerInfo> getServerInfos();
+
+ /**
* Deletes the current profile (but has no effect on sessions and events). This will delete the
* persisted profile and replace it with a new empty one with the same profileId.
* @param profileId the identifier of the profile to delete and replace
diff --git a/extensions/privacy-extension/rest/src/main/java/org/apache/unomi/privacy/rest/PrivacyServiceEndPoint.java b/extensions/privacy-extension/rest/src/main/java/org/apache/unomi/privacy/rest/PrivacyServiceEndPoint.java
index c4c990a..8c3dafc 100644
--- a/extensions/privacy-extension/rest/src/main/java/org/apache/unomi/privacy/rest/PrivacyServiceEndPoint.java
+++ b/extensions/privacy-extension/rest/src/main/java/org/apache/unomi/privacy/rest/PrivacyServiceEndPoint.java
@@ -57,6 +57,12 @@ public class PrivacyServiceEndPoint {
return privacyService.getServerInfo();
}
+ @GET
+ @Path("/infos")
+ public List<ServerInfo> getServerInfos() {
+ return privacyService.getServerInfos();
+ }
+
@DELETE
@Path("/profiles/{profileId}")
public Response deleteProfileData(@PathParam("profileId") String profileId, @QueryParam("withData") @DefaultValue("false") boolean withData,
diff --git a/extensions/privacy-extension/services/pom.xml b/extensions/privacy-extension/services/pom.xml
index 5a0ede7..b7e337d 100644
--- a/extensions/privacy-extension/services/pom.xml
+++ b/extensions/privacy-extension/services/pom.xml
@@ -53,6 +53,12 @@
<artifactId>osgi.core</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-lifecycle-watcher</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/extensions/privacy-extension/services/src/main/java/org/apache/unomi/privacy/internal/PrivacyServiceImpl.java b/extensions/privacy-extension/services/src/main/java/org/apache/unomi/privacy/internal/PrivacyServiceImpl.java
index 3d3d68d..64c3a5f 100644
--- a/extensions/privacy-extension/services/src/main/java/org/apache/unomi/privacy/internal/PrivacyServiceImpl.java
+++ b/extensions/privacy-extension/services/src/main/java/org/apache/unomi/privacy/internal/PrivacyServiceImpl.java
@@ -21,6 +21,7 @@ import org.apache.unomi.api.*;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.PrivacyService;
import org.apache.unomi.api.services.ProfileService;
+import org.apache.unomi.lifecycle.BundleWatcher;
import org.apache.unomi.persistence.spi.PersistenceService;
import org.apache.unomi.persistence.spi.aggregate.TermsAggregate;
import org.osgi.framework.BundleContext;
@@ -40,6 +41,7 @@ public class PrivacyServiceImpl implements PrivacyService {
private ProfileService profileService;
private EventService eventService;
private BundleContext bundleContext;
+ private BundleWatcher bundleWatcher;
public PrivacyServiceImpl() {
logger.info("Initializing privacy service...");
@@ -61,12 +63,20 @@ public class PrivacyServiceImpl implements PrivacyService {
this.bundleContext = bundleContext;
}
+ public void setBundleWatcher(BundleWatcher bundleWatcher) {
+ this.bundleWatcher = bundleWatcher;
+ }
+
@Override
public ServerInfo getServerInfo() {
- ServerInfo serverInfo = new ServerInfo();
- serverInfo.setServerIdentifier("Apache Unomi");
- serverInfo.setServerVersion(bundleContext.getBundle().getVersion().toString());
+ List<ServerInfo> serverInfos = bundleWatcher.getServerInfos();
+ ServerInfo serverInfo = serverInfos.get(0); // Unomi is always be the first entry
+
+ addUnomiInfo(serverInfo);
+ return serverInfo;
+ }
+ private void addUnomiInfo(ServerInfo serverInfo) {
// let's retrieve all the event types the server has seen.
Map<String, Long> eventTypeCounts = persistenceService.aggregateWithOptimizedQuery(null, new TermsAggregate("eventType"), Event.ITEM_TYPE);
List<EventInfo> eventTypes = new ArrayList<EventInfo>();
@@ -79,7 +89,12 @@ public class PrivacyServiceImpl implements PrivacyService {
serverInfo.setEventTypes(eventTypes);
serverInfo.setCapabilities(new HashMap<String, String>());
- return serverInfo;
+ }
+
+ public List<ServerInfo> getServerInfos() {
+ List<ServerInfo> serverInfos = bundleWatcher.getServerInfos();
+ addUnomiInfo(serverInfos.get(0));
+ return serverInfos;
}
@Override
diff --git a/extensions/privacy-extension/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/extensions/privacy-extension/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 1b56fe9..85f9e3c 100644
--- a/extensions/privacy-extension/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/extensions/privacy-extension/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -29,6 +29,8 @@
<reference id="profileService" interface="org.apache.unomi.api.services.ProfileService"/>
+ <reference id="bundleWatcher" interface="org.apache.unomi.lifecycle.BundleWatcher" />
+
<!-- Privacy service -->
<bean id="privacyServiceImpl" class="org.apache.unomi.privacy.internal.PrivacyServiceImpl">
@@ -36,6 +38,7 @@
<property name="eventService" ref="eventService" />
<property name="profileService" ref="profileService" />
<property name="bundleContext" ref="blueprintBundleContext"/>
+ <property name="bundleWatcher" ref="bundleWatcher"/>
</bean>
<service id="privacyService" ref="privacyServiceImpl" interface="org.apache.unomi.api.services.PrivacyService"/>
</blueprint>
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 fc15ed4..9f62673 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
@@ -34,7 +34,7 @@ public class CDPEventInterfaceResolver extends BaseTypeResolver {
final CDPEventInterface eventInterface = env.getObject();
final JSONSchema eventSchema = schemaRegistry.getSchema("https://unomi.apache.org/schemas/json/events/" + eventInterface.getEvent().getEventType() + "/1-0-0");
if (eventSchema != null) {
- final String typeName = UnomiToGraphQLConverter.convertEventType(eventSchema.getSchemaId());
+ final String typeName = UnomiToGraphQLConverter.convertEventType(eventSchema.getName());
return env.getSchema().getObjectType(typeName);
} else {
return super.getType(env);
diff --git a/itests/src/test/java/org/apache/unomi/itests/AllITs.java b/itests/src/test/java/org/apache/unomi/itests/AllITs.java
index d632872..facb730 100644
--- a/itests/src/test/java/org/apache/unomi/itests/AllITs.java
+++ b/itests/src/test/java/org/apache/unomi/itests/AllITs.java
@@ -51,6 +51,7 @@ import org.junit.runners.Suite.SuiteClasses;
ContextServletIT.class,
SecurityIT.class,
RuleServiceIT.class,
+ PrivacyServiceIT.class,
GroovyActionsServiceIT.class,
GraphQLEventIT.class,
GraphQLListIT.class,
diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
index d39569b..102d107 100644
--- a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
@@ -19,6 +19,22 @@ package org.apache.unomi.itests;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.*;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.unomi.api.Item;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.api.rules.Rule;
@@ -28,6 +44,7 @@ import org.apache.unomi.api.services.SchemaRegistry;
import org.apache.unomi.lifecycle.BundleWatcher;
import org.apache.unomi.persistence.spi.CustomObjectMapper;
import org.apache.unomi.persistence.spi.PersistenceService;
+import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
@@ -51,8 +68,16 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.function.Predicate;
@@ -77,6 +102,11 @@ public abstract class BaseIT {
protected static final String URL = "http://localhost:" + HTTP_PORT;
protected static final String KARAF_DIR = "target/exam";
protected static final String UNOMI_KEY = "670c26d1cc413346c3b2fd9ce65dab41";
+ protected static final ContentType JSON_CONTENT_TYPE = ContentType.create("application/json");
+ protected static final String BASE_URL = "http://localhost";
+ protected static final String BASIC_AUTH_USER_NAME = "karaf";
+ protected static final String BASIC_AUTH_PASSWORD = "karaf";
+ protected static final int REQUEST_TIMEOUT = 60000;
@Inject
@Filter(timeout = 600000)
@@ -104,14 +134,24 @@ public abstract class BaseIT {
@Filter(timeout = 600000)
protected SchemaRegistry schemaRegistry;
+ private CloseableHttpClient httpClient;
+
@Before
public void waitForStartup() throws InterruptedException {
while (!bundleWatcher.isStartupComplete()) {
LOGGER.info("Waiting for startup to complete...");
Thread.sleep(1000);
}
+ httpClient = initHttpClient();
+ }
+
+ @After
+ public void shutdown() {
+ closeHttpClient(httpClient);
+ httpClient = null;
}
+
protected void removeItems(final Class<? extends Item> ...classes) throws InterruptedException {
Condition condition = new Condition(definitionsService.getConditionType("matchAllCondition"));
for (Class<? extends Item> aClass : classes) {
@@ -362,4 +402,162 @@ public abstract class BaseIT {
100);
rulesService.refreshRules();
}
+
+ public String getFullUrl(String url) throws Exception {
+ return BASE_URL + ":" + HTTP_PORT + url;
+ }
+
+ protected <T> T get(final String url, Class<T> clazz) {
+ CloseableHttpResponse response = null;
+ try {
+ final HttpGet httpGet = new HttpGet(getFullUrl(url));
+ response = executeHttpRequest(httpGet);
+ if (response.getStatusLine().getStatusCode() == 200) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ return objectMapper.readValue(response.getEntity().getContent(), clazz);
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (response != null) {
+ try {
+ response.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return null;
+ }
+
+ protected CloseableHttpResponse post(final String url, final String resource) {
+ try {
+ final HttpPost request = new HttpPost(getFullUrl(url));
+
+ if (resource != null) {
+ final String resourceAsString = resourceAsString(resource);
+ request.setEntity(new StringEntity(resourceAsString, JSON_CONTENT_TYPE));
+ }
+
+ return executeHttpRequest(request);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ protected void delete(final String url) {
+ CloseableHttpResponse response = null;
+ try {
+ final HttpDelete httpDelete = new HttpDelete(getFullUrl(url));
+ response = executeHttpRequest(httpDelete);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (response != null) {
+ try {
+ response.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ protected CloseableHttpResponse executeHttpRequest(HttpUriRequest request) throws IOException {
+ System.out.println("Executing request " + request.getMethod() + " " + request.getURI() + "...");
+ CloseableHttpResponse response = httpClient.execute(request);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ String content = null;
+ if (response.getEntity() != null) {
+ InputStream contentInputStream = response.getEntity().getContent();
+ if (contentInputStream != null) {
+ content = IOUtils.toString(response.getEntity().getContent());
+ }
+ }
+ LOGGER.error("Response status code: {}, reason: {}, content:{}", response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), content);
+ }
+ return response;
+ }
+
+ protected String resourceAsString(final String resource) {
+ final java.net.URL url = bundleContext.getBundle().getResource(resource);
+ try (InputStream stream = url.openStream()) {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ return objectMapper.writeValueAsString(objectMapper.readTree(stream));
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static CloseableHttpClient initHttpClient() {
+ long requestStartTime = System.currentTimeMillis();
+ BasicCredentialsProvider credsProvider = null;
+ credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(
+ AuthScope.ANY,
+ new UsernamePasswordCredentials(BASIC_AUTH_USER_NAME, BASIC_AUTH_PASSWORD));
+ HttpClientBuilder httpClientBuilder = HttpClients.custom().useSystemProperties().setDefaultCredentialsProvider(credsProvider);
+
+ try {
+ SSLContext sslContext = SSLContext.getInstance("SSL");
+ sslContext.init(null, new TrustManager[]{new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs,
+ String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs,
+ String authType) {
+ }
+ }}, new SecureRandom());
+
+ Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER))
+ .build();
+
+ PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+ poolingHttpClientConnectionManager.setMaxTotal(10);
+
+ httpClientBuilder.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
+ .setConnectionManager(poolingHttpClientConnectionManager);
+
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ LOGGER.error("Error creating SSL Context", e);
+ }
+
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setConnectTimeout(REQUEST_TIMEOUT)
+ .setSocketTimeout(REQUEST_TIMEOUT)
+ .setConnectionRequestTimeout(REQUEST_TIMEOUT)
+ .build();
+ httpClientBuilder.setDefaultRequestConfig(requestConfig);
+
+ if (LOGGER.isDebugEnabled()) {
+ long totalRequestTime = System.currentTimeMillis() - requestStartTime;
+ LOGGER.debug("Init HttpClient executed in " + totalRequestTime + "ms");
+ }
+
+ return httpClientBuilder.build();
+ }
+
+ public static void closeHttpClient(CloseableHttpClient httpClient) {
+ try {
+ if (httpClient != null) {
+ httpClient.close();
+ }
+ } catch (IOException e) {
+ LOGGER.error("Could not close httpClient: " + httpClient, e);
+ }
+ }
+
}
diff --git a/itests/src/test/java/org/apache/unomi/itests/PrivacyServiceIT.java b/itests/src/test/java/org/apache/unomi/itests/PrivacyServiceIT.java
new file mode 100644
index 0000000..0c4f8a3
--- /dev/null
+++ b/itests/src/test/java/org/apache/unomi/itests/PrivacyServiceIT.java
@@ -0,0 +1,81 @@
+/*
+ * 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.itests;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.apache.unomi.api.PartialList;
+import org.apache.unomi.persistence.spi.CustomObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerSuite;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerSuite.class)
+public class PrivacyServiceIT extends BaseIT {
+
+ protected static final String PRIVACY_ENDPOINT = "/cxs/privacy";
+ private static final int DEFAULT_TRYING_TIMEOUT = 2000;
+ private static final int DEFAULT_TRYING_TRIES = 30;
+
+ @Before
+ public void setUp() throws InterruptedException, IOException {
+ keepTrying("Couldn't find privacy endpoint",
+ () -> get(PRIVACY_ENDPOINT + "/info", Map.class),
+ serverInfo -> serverInfo != null,
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+ }
+
+ @Test
+ public void testServerInfo() throws IOException {
+ Map<String,Object> serverInfo = get(PRIVACY_ENDPOINT + "/info", Map.class);
+ assertNotNull("Server info is null", serverInfo);
+ assertEquals("Server identifier is incorrect", "Apache Unomi", serverInfo.get("serverIdentifier"));
+ }
+
+ @Test
+ public void testServerInfos() throws IOException {
+ List<Map<String,Object>> serverInfos = get(PRIVACY_ENDPOINT + "/infos", List.class);
+ assertEquals("Server info list is invalid", 1, serverInfos.size());
+ assertEquals("Server identifier is incorrect", "Apache Unomi", serverInfos.get(0).get("serverIdentifier"));
+ }
+
+}
diff --git a/itests/src/test/resources/schemas/events/negative-test-event-type.json b/itests/src/test/resources/schemas/events/negative-test-event-type.json
new file mode 100644
index 0000000..fe4d299
--- /dev/null
+++ b/itests/src/test/resources/schemas/events/negative-test-event-type.json
@@ -0,0 +1,13 @@
+{
+ "$id": "https://unomi.apache.org/schemas/json/events/negative-test-event-type/1-0-0",
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "self":{
+ "vendor":"org.apache.unomi",
+ "name":"events/negative-test-event-type",
+ "format":"jsonschema",
+ "version":"1-0-0"
+ },
+ "title": "TestEvent",
+ "type": "object",
+ "allOf": [{ "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" }]
+}
\ No newline at end of file
diff --git a/lifecycle-watcher/pom.xml b/lifecycle-watcher/pom.xml
index 93a60ec..f3a5192 100644
--- a/lifecycle-watcher/pom.xml
+++ b/lifecycle-watcher/pom.xml
@@ -34,6 +34,12 @@
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
@@ -64,6 +70,8 @@
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Implementation-Build>${buildNumber}</Implementation-Build>
<Implementation-TimeStamp>${timestamp}</Implementation-TimeStamp>
+ <Implementation-ScmBranch>${scmBranch}</Implementation-ScmBranch>
+ <Implementation-ServerIdentifier>Apache Unomi</Implementation-ServerIdentifier>
</instructions>
</configuration>
</plugin>
diff --git a/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java b/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java
index 31eec3b..06c28a6 100644
--- a/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java
+++ b/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java
@@ -16,276 +16,24 @@
*/
package org.apache.unomi.lifecycle;
-import org.osgi.framework.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.unomi.api.ServerInfo;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimerTask;
-import java.util.concurrent.*;
-import java.util.stream.Collectors;
/**
- * This class listens to the global Apache Unomi bundle lifecycle, to provide statistics and state of the overall
- * system. It notably displays messages for successfull or unsuccessfull startups as well as startup times.
+ * Interface for the bundle watcher system in Apache Unomi. It allows to know if startup has completed as well as
+ * server information such as identifier, versions, build information and more.
*/
-public class BundleWatcher implements SynchronousBundleListener, ServiceListener {
+public interface BundleWatcher {
- private static final Logger logger = LoggerFactory.getLogger(BundleWatcher.class.getName());
+ /**
+ * Retrieves the list of the server information objects, that include extensions. Each object includes the
+ * name and version of the server, build time information and the event types
+ * if recognizes as well as the capabilities supported by the system.
+ * @return a list of ServerInfo objects with all the server information
+ */
+ List<ServerInfo> getServerInfos();
- private long startupTime;
- private Map<String, Boolean> requiredBundles = new ConcurrentHashMap<>();
-
- private ScheduledExecutorService scheduler;
- private ScheduledFuture<?> scheduledFuture;
-
- private String requiredServices;
- private Set<Filter> requiredServicesFilters = new LinkedHashSet<>();
- private long matchedRequiredServicesCount = 0;
-
- private BundleContext bundleContext;
- private boolean startupMessageAlreadyDisplayed = false;
- private boolean shutdownMessageAlreadyDisplayed = false;
- private List<String> logoLines = new ArrayList<>();
-
- private Integer checkStartupStateRefreshInterval = 60;
-
- public void setRequiredBundles(Map<String, Boolean> requiredBundles) {
- this.requiredBundles = new ConcurrentHashMap<>(requiredBundles);
- }
-
- public void setCheckStartupStateRefreshInterval(Integer checkStartupStateRefreshInterval) {
- this.checkStartupStateRefreshInterval = checkStartupStateRefreshInterval;
- }
-
- public void setRequiredServices(String requiredServices) {
- this.requiredServices = requiredServices;
- String[] requiredServiceArray = requiredServices.split(",");
- requiredServicesFilters.clear();
- for (String requiredService : requiredServiceArray) {
- try {
- requiredServicesFilters.add(bundleContext.createFilter(requiredService.trim()));
- } catch (InvalidSyntaxException e) {
- logger.error("Error creating require service filter {}", requiredService.trim(), e);
- }
- }
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void init() {
- scheduler = Executors.newSingleThreadScheduledExecutor();
- checkExistingBundles();
- bundleContext.addBundleListener(this);
- bundleContext.addServiceListener(this);
- loadLogo();
- startupTime = System.currentTimeMillis();
- System.out.println("Initializing Unomi...");
- logger.info("Bundle watcher initialized.");
- }
-
- private boolean allBundleStarted() {
- return getInactiveBundles().isEmpty();
- }
-
- private void displayLogsForInactiveBundles() {
- getInactiveBundles().forEach(inactiveBundle -> logger
- .warn("The bundle {} is in not active, some errors could happen when using the application", inactiveBundle));
- }
-
- private List<String> getInactiveBundles() {
- return requiredBundles.entrySet().stream().filter(entry -> !entry.getValue()).map(Map.Entry::getKey).collect(Collectors.toList());
-
- }
-
- public void destroy() {
- bundleContext.removeServiceListener(this);
- bundleContext.removeBundleListener(this);
- if (scheduledFuture != null) {
- scheduledFuture.cancel(true);
- }
- logger.info("Bundle watcher shutdown.");
- }
-
- public void checkExistingBundles() {
- for (Bundle bundle : bundleContext.getBundles()) {
- if (bundle.getSymbolicName().startsWith("org.apache.unomi") && requiredBundles.containsKey(bundle.getSymbolicName())) {
- if (bundle.getState() == Bundle.ACTIVE) {
- requiredBundles.put(bundle.getSymbolicName(), true);
- } else {
- requiredBundles.put(bundle.getSymbolicName(), false);
- }
- }
- }
- checkStartupComplete();
- }
-
- @Override
- public void bundleChanged(BundleEvent event) {
- switch (event.getType()) {
- case BundleEvent.STARTING:
- break;
- case BundleEvent.STARTED:
- if (event.getBundle().getSymbolicName().startsWith("org.apache.unomi") && requiredBundles.containsKey(event.getBundle().getSymbolicName())) {
- logger.info("Bundle {} was started.", event.getBundle().getSymbolicName());
- requiredBundles.put(event.getBundle().getSymbolicName(), true);
- checkStartupComplete();
- }
- break;
- case BundleEvent.STOPPING:
- break;
- case BundleEvent.STOPPED:
- if (event.getBundle().getSymbolicName().startsWith("org.apache.unomi") && requiredBundles.containsKey(event.getBundle().getSymbolicName())) {
- logger.info("Bundle {} was stopped", event.getBundle().getSymbolicName());
- requiredBundles.put(event.getBundle().getSymbolicName(), false);
- }
- break;
- default:
- break;
- }
- }
-
- @Override
- public void serviceChanged(ServiceEvent event) {
- ServiceReference serviceReference = event.getServiceReference();
- if (serviceReference == null) {
- return;
- }
- switch (event.getType()) {
- case ServiceEvent.REGISTERED:
- addStartedService(serviceReference);
- checkStartupComplete();
- break;
- case ServiceEvent.MODIFIED:
- break;
- case ServiceEvent.UNREGISTERING:
- removeStartedService(serviceReference);
- break;
- }
- }
-
- private void addStartedService(ServiceReference serviceReference) {
- for (Filter requiredService : requiredServicesFilters) {
- if (requiredService.match(serviceReference)) {
- matchedRequiredServicesCount++;
- }
- }
- }
-
- private void removeStartedService(ServiceReference serviceReference) {
- for (Filter requiredService : requiredServicesFilters) {
- if (requiredService.match(serviceReference)) {
- matchedRequiredServicesCount--;
- if (!shutdownMessageAlreadyDisplayed) {
- System.out.println("Apache Unomi shutting down...");
- logger.info("Apache Unomi no longer available, as required service {} is shutdown !", serviceReference);
- shutdownMessageAlreadyDisplayed = true;
- }
- startupMessageAlreadyDisplayed = false;
- }
- }
- }
-
- private void displayLogsForInactiveServices() {
- requiredServicesFilters.forEach(requiredServicesFilter -> {
- ServiceReference[] serviceReference = new ServiceReference[0];
- String filterToString = requiredServicesFilter.toString();
- try {
- serviceReference = bundleContext.getServiceReferences((String) null, filterToString);
- } catch (InvalidSyntaxException e) {
- logger.error("Failed to get the service reference for {}", filterToString, e);
- }
- if (serviceReference == null) {
- logger.warn("No service found for the filter {}, some errors could happen when using the application", filterToString);
- }
- });
- }
-
- private void checkStartupComplete() {
- if (!isStartupComplete()) {
- if (scheduledFuture == null || scheduledFuture.isCancelled()) {
- TimerTask task = new TimerTask() {
- @Override
- public void run() {
- displayLogsForInactiveBundles();
- displayLogsForInactiveServices();
- checkStartupComplete();
- }
- };
- scheduledFuture = scheduler
- .scheduleWithFixedDelay(task, checkStartupStateRefreshInterval, checkStartupStateRefreshInterval, TimeUnit.SECONDS);
- }
- return;
- }
- if (scheduledFuture != null) {
- scheduledFuture.cancel(true);
- scheduledFuture = null;
- }
- if (!startupMessageAlreadyDisplayed) {
- long totalStartupTime = System.currentTimeMillis() - startupTime;
- if (!logoLines.isEmpty()) {
- logoLines.forEach(System.out::println);
- }
- String buildNumber = "n/a";
- if (bundleContext.getBundle().getHeaders().get("Implementation-Build") != null) {
- buildNumber = bundleContext.getBundle().getHeaders().get("Implementation-Build");
- }
- String timestamp = "n/a";
- if (bundleContext.getBundle().getHeaders().get("Implementation-TimeStamp") != null) {
- timestamp = bundleContext.getBundle().getHeaders().get("Implementation-TimeStamp");
- }
- String versionMessage =
- " " + bundleContext.getBundle().getVersion().toString() + " Build:" + buildNumber + " Timestamp:" + timestamp;
- System.out.println(versionMessage);
- System.out.println("--------------------------------------------------------------------------");
- System.out.println(
- "Successfully started " + requiredBundles.size() + " bundles and " + requiredServicesFilters.size() + " " + "required "
- + "services in " + totalStartupTime + " ms");
- logger.info("Apache Unomi version: {}", versionMessage);
- logger.info("Apache Unomi successfully started {} bundles and {} required services in {} ms", requiredBundles.size(),
- requiredServicesFilters.size(), totalStartupTime);
- startupMessageAlreadyDisplayed = true;
- shutdownMessageAlreadyDisplayed = false;
- }
- }
-
- public boolean isStartupComplete() {
- return allBundleStarted() && matchedRequiredServicesCount == requiredServicesFilters.size();
- }
-
- private void loadLogo() {
- URL logoURL = bundleContext.getBundle().getResource("logo.txt");
- if (logoURL != null) {
- BufferedReader bufferedReader = null;
- try {
- bufferedReader = new BufferedReader(new InputStreamReader(logoURL.openStream()));
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- if (!line.trim().startsWith("#")) {
- logoLines.add(line);
- }
- }
- } catch (IOException e) {
- logger.error("Error loading logo lines", e);
- } finally {
- if (bufferedReader != null) {
- try {
- bufferedReader.close();
- } catch (IOException e) {
- }
- }
- }
- }
- }
+ boolean isStartupComplete();
}
diff --git a/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java b/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcherImpl.java
similarity index 71%
copy from lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java
copy to lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcherImpl.java
index 31eec3b..b57fcfa 100644
--- a/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java
+++ b/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcherImpl.java
@@ -16,6 +16,8 @@
*/
package org.apache.unomi.lifecycle;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.unomi.api.ServerInfo;
import org.osgi.framework.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,12 +26,8 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimerTask;
+import java.text.MessageFormat;
+import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@@ -37,9 +35,9 @@ import java.util.stream.Collectors;
* This class listens to the global Apache Unomi bundle lifecycle, to provide statistics and state of the overall
* system. It notably displays messages for successfull or unsuccessfull startups as well as startup times.
*/
-public class BundleWatcher implements SynchronousBundleListener, ServiceListener {
+public class BundleWatcherImpl implements SynchronousBundleListener, ServiceListener, BundleWatcher {
- private static final Logger logger = LoggerFactory.getLogger(BundleWatcher.class.getName());
+ private static final Logger logger = LoggerFactory.getLogger(BundleWatcherImpl.class.getName());
private long startupTime;
private Map<String, Boolean> requiredBundles = new ConcurrentHashMap<>();
@@ -58,6 +56,8 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
private Integer checkStartupStateRefreshInterval = 60;
+ private List<ServerInfo> serverInfos = new ArrayList<>();
+
public void setRequiredBundles(Map<String, Boolean> requiredBundles) {
this.requiredBundles = new ConcurrentHashMap<>(requiredBundles);
}
@@ -88,12 +88,16 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
checkExistingBundles();
bundleContext.addBundleListener(this);
bundleContext.addServiceListener(this);
- loadLogo();
startupTime = System.currentTimeMillis();
System.out.println("Initializing Unomi...");
logger.info("Bundle watcher initialized.");
}
+ @Override
+ public List<ServerInfo> getServerInfos() {
+ return serverInfos;
+ }
+
private boolean allBundleStarted() {
return getInactiveBundles().isEmpty();
}
@@ -118,6 +122,8 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
}
public void checkExistingBundles() {
+ serverInfos.clear();
+ serverInfos.add(getBundleServerInfo(bundleContext.getBundle())); // make sure the first server info is the default one
for (Bundle bundle : bundleContext.getBundles()) {
if (bundle.getSymbolicName().startsWith("org.apache.unomi") && requiredBundles.containsKey(bundle.getSymbolicName())) {
if (bundle.getState() == Bundle.ACTIVE) {
@@ -126,6 +132,12 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
requiredBundles.put(bundle.getSymbolicName(), false);
}
}
+ if (!bundle.getSymbolicName().equals(bundleContext.getBundle().getSymbolicName())) {
+ ServerInfo serverInfo = getBundleServerInfo(bundle);
+ if (serverInfo != null) {
+ serverInfos.add(serverInfo);
+ }
+ }
}
checkStartupComplete();
}
@@ -233,39 +245,44 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
}
if (!startupMessageAlreadyDisplayed) {
long totalStartupTime = System.currentTimeMillis() - startupTime;
- if (!logoLines.isEmpty()) {
+
+ List<String> logoLines = serverInfos.get(serverInfos.size()-1).getLogoLines();
+ if (logoLines != null && !logoLines.isEmpty()) {
logoLines.forEach(System.out::println);
}
- String buildNumber = "n/a";
- if (bundleContext.getBundle().getHeaders().get("Implementation-Build") != null) {
- buildNumber = bundleContext.getBundle().getHeaders().get("Implementation-Build");
- }
- String timestamp = "n/a";
- if (bundleContext.getBundle().getHeaders().get("Implementation-TimeStamp") != null) {
- timestamp = bundleContext.getBundle().getHeaders().get("Implementation-TimeStamp");
- }
- String versionMessage =
- " " + bundleContext.getBundle().getVersion().toString() + " Build:" + buildNumber + " Timestamp:" + timestamp;
- System.out.println(versionMessage);
- System.out.println("--------------------------------------------------------------------------");
+ System.out.println("--------------------------------------------------------------------------------------------");
+ serverInfos.forEach(serverInfo -> {
+ String versionMessage = MessageFormat.format(" {0} {1} ({2,date,yyyy-MM-dd HH:mm:ssZ} // {3} // {4} // {5}) ",
+ StringUtils.rightPad(serverInfo.getServerIdentifier(), 12, " "),
+ serverInfo.getServerVersion(),
+ serverInfo.getServerBuildDate(),
+ serverInfo.getServerTimestamp(),
+ serverInfo.getServerScmBranch(),
+ serverInfo.getServerBuildNumber()
+ );
+ System.out.println(versionMessage);
+ logger.info(versionMessage);
+ });
+ System.out.println("--------------------------------------------------------------------------------------------");
System.out.println(
- "Successfully started " + requiredBundles.size() + " bundles and " + requiredServicesFilters.size() + " " + "required "
+ "Server successfully started " + requiredBundles.size() + " bundles and " + requiredServicesFilters.size() + " required "
+ "services in " + totalStartupTime + " ms");
- logger.info("Apache Unomi version: {}", versionMessage);
- logger.info("Apache Unomi successfully started {} bundles and {} required services in {} ms", requiredBundles.size(),
+ logger.info("Server successfully started {} bundles and {} required services in {} ms", requiredBundles.size(),
requiredServicesFilters.size(), totalStartupTime);
startupMessageAlreadyDisplayed = true;
shutdownMessageAlreadyDisplayed = false;
}
}
+ @Override
public boolean isStartupComplete() {
return allBundleStarted() && matchedRequiredServicesCount == requiredServicesFilters.size();
}
- private void loadLogo() {
- URL logoURL = bundleContext.getBundle().getResource("logo.txt");
+ private List<String> loadLogo(Bundle bundle) {
+ URL logoURL = bundle.getResource("unomi-logo.txt");
if (logoURL != null) {
+ List<String> logoLines = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(logoURL.openStream()));
@@ -275,6 +292,7 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
logoLines.add(line);
}
}
+ return logoLines;
} catch (IOException e) {
logger.error("Error loading logo lines", e);
} finally {
@@ -286,6 +304,52 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener
}
}
}
+ return null;
+ }
+
+ public ServerInfo getBundleServerInfo(Bundle bundle) {
+ String serverIdentifier = "n/a";
+ if (bundle.getHeaders().get("Implementation-ServerIdentifier") != null) {
+ serverIdentifier = bundle.getHeaders().get("Implementation-ServerIdentifier");
+ } else {
+ return null;
+ }
+ List<String> logoLines = loadLogo(bundle);
+ String buildNumber = "n/a";
+ if (bundle.getHeaders().get("Implementation-Build") != null) {
+ buildNumber = bundle.getHeaders().get("Implementation-Build");
+ }
+ String timestamp = "n/a";
+ Date buildDate = null;
+ if (bundle.getHeaders().get("Implementation-TimeStamp") != null) {
+ timestamp = bundle.getHeaders().get("Implementation-TimeStamp");
+ try {
+ buildDate = new Date(Long.parseLong(timestamp));
+ } catch (Throwable t) {
+ // we simply ignore this exception and keep the timestamp as it is
+ }
+ }
+ String scmBranch = "n/a";
+ if (bundle.getHeaders().get("Implementation-ScmBranch") != null) {
+ scmBranch = bundle.getHeaders().get("Implementation-ScmBranch");
+ }
+ if (bundle.getHeaders().get("Implementation-UnomiEventTypes") != null) {
+ // to be implemented
+ }
+ if (bundle.getHeaders().get("Implementation-UnomiCapabilities") != null) {
+ // to be implemented
+ }
+ ServerInfo serverInfo = new ServerInfo();
+ serverInfo.setServerIdentifier(serverIdentifier);
+ serverInfo.setServerVersion(bundle.getVersion().toString());
+ serverInfo.setServerBuildNumber(buildNumber);
+ serverInfo.setServerBuildDate(buildDate);
+ serverInfo.setServerTimestamp(timestamp);
+ serverInfo.setServerScmBranch(scmBranch);
+ if (logoLines != null) {
+ serverInfo.setLogoLines(logoLines);
+ }
+ return serverInfo;
}
}
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 1bb5a53..050a2ae 100644
--- a/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -30,7 +30,7 @@
</cm:default-properties>
</cm:property-placeholder>
- <bean id="bundleWatcher" init-method="init" destroy-method="destroy" class="org.apache.unomi.lifecycle.BundleWatcher">
+ <bean id="bundleWatcherImpl" init-method="init" destroy-method="destroy" class="org.apache.unomi.lifecycle.BundleWatcherImpl">
<property name="bundleContext" ref="blueprintBundleContext"/>
<property name="requiredServices" value="${lifecycle.requiredServices}" />
<property name="checkStartupStateRefreshInterval" value="${lifecycle.checkStartupState.refresh.interval}"/>
@@ -67,7 +67,7 @@
</property>
</bean>
- <service id="bundleWatcherService" ref="bundleWatcher">
+ <service id="bundleWatcherService" ref="bundleWatcherImpl">
<interfaces>
<value>org.apache.unomi.lifecycle.BundleWatcher</value>
</interfaces>
diff --git a/lifecycle-watcher/src/main/resources/logo.txt b/lifecycle-watcher/src/main/resources/unomi-logo.txt
similarity index 93%
rename from lifecycle-watcher/src/main/resources/logo.txt
rename to lifecycle-watcher/src/main/resources/unomi-logo.txt
index 0db2b87..1a509ad 100644
--- a/lifecycle-watcher/src/main/resources/logo.txt
+++ b/lifecycle-watcher/src/main/resources/unomi-logo.txt
@@ -22,5 +22,3 @@
| | / | ( <_> ) Y Y \ |
|______/|___| /\____/|__|_| /__|
\/ \/
-
---------------------------------------------------------------------------
\ No newline at end of file
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
index 4c5796d..2375e7b 100644
--- 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
@@ -33,7 +33,7 @@ class UnomiPropertyTypeKeyword extends AbstractKeyword {
private final ProfileService profileService;
private final SchemaRegistryImpl schemaRegistry;
- private static final class PropertyTypeJsonValidator extends AbstractJsonValidator {
+ private static final class UnomiPropertyTypeJsonValidator extends AbstractJsonValidator {
String schemaPath;
JsonNode schemaNode;
@@ -42,7 +42,7 @@ class UnomiPropertyTypeKeyword extends AbstractKeyword {
ProfileService profileService;
SchemaRegistryImpl schemaRegistry;
- public PropertyTypeJsonValidator(String keyword, String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext, ProfileService profileService, SchemaRegistryImpl schemaRegistry) {
+ public UnomiPropertyTypeJsonValidator(String keyword, String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext, ProfileService profileService, SchemaRegistryImpl schemaRegistry) {
super(keyword);
this.schemaPath = schemaPath;
this.schemaNode = schemaNode;
@@ -105,6 +105,6 @@ class UnomiPropertyTypeKeyword extends AbstractKeyword {
@Override
public JsonValidator newValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) throws JsonSchemaException, Exception {
- return new PropertyTypeJsonValidator(this.getValue(), schemaPath, schemaNode, parentSchema, validationContext, profileService, schemaRegistry);
+ return new UnomiPropertyTypeJsonValidator(this.getValue(), schemaPath, schemaNode, parentSchema, validationContext, profileService, schemaRegistry);
}
}
diff --git a/services/src/main/resources/META-INF/cxs/schemas/events/view.json b/services/src/main/resources/META-INF/cxs/schemas/events/view.json
index a85188a..1840449 100644
--- a/services/src/main/resources/META-INF/cxs/schemas/events/view.json
+++ b/services/src/main/resources/META-INF/cxs/schemas/events/view.json
@@ -14,7 +14,6 @@
"properties" : {
"properties" : {
"type" : "object",
- "unomiPropertyTypes" : [ "events" ],
"maxProperties": 50
},
"source" : {