You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by am...@apache.org on 2017/05/23 00:30:34 UTC
[2/3] incubator-unomi git commit: DMF-1343 Import profiles from CSV
through API
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/router/router-rest/src/main/java/org/apache/unomi/router/rest/ImportConfigurationServiceEndPoint.java
----------------------------------------------------------------------
diff --git a/router/router-rest/src/main/java/org/apache/unomi/router/rest/ImportConfigurationServiceEndPoint.java b/router/router-rest/src/main/java/org/apache/unomi/router/rest/ImportConfigurationServiceEndPoint.java
new file mode 100644
index 0000000..e81930a
--- /dev/null
+++ b/router/router-rest/src/main/java/org/apache/unomi/router/rest/ImportConfigurationServiceEndPoint.java
@@ -0,0 +1,167 @@
+/*
+ * 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.router.rest;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.unomi.router.api.ImportConfiguration;
+import org.apache.unomi.router.api.services.ImportConfigurationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+/**
+ * A JAX-RS endpoint to manage {@link org.apache.unomi.router.api.ImportConfiguration}s.
+ */
+@WebService
+@CrossOriginResourceSharing(
+ allowAllOrigins = true,
+ allowCredentials = true
+)
+public class ImportConfigurationServiceEndPoint {
+
+ private static final Logger logger = LoggerFactory.getLogger(ImportConfigurationServiceEndPoint.class.getName());
+
+ private ImportConfigurationService importConfigurationService;
+ private String uploadDir;
+
+ public ImportConfigurationServiceEndPoint () {
+ logger.info("Initializing import configuration service endpoint...");
+ }
+
+ @WebMethod(exclude = true)
+ public void setImportConfigurationService(ImportConfigurationService importConfigurationService) {
+ this.importConfigurationService = importConfigurationService;
+ }
+
+ @WebMethod(exclude = true)
+ public void setUploadDir(String uploadDir) {
+ this.uploadDir = uploadDir;
+ }
+
+ /**
+ * Retrieves all the import configurations.
+ *
+ * @return all the import configurations.
+ */
+ @GET
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public List<ImportConfiguration> getImportConfigurations() {
+ return importConfigurationService.getImportConfigurations();
+ }
+
+ /**
+ * Retrieves an import configuration by id.
+ *
+ * @return the import configuration that matches the given id.
+ */
+ @GET
+ @Path("/{configId}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public ImportConfiguration getImportConfiguration(@PathParam("configId") String configId) {
+ return importConfigurationService.load(configId);
+ }
+
+ /**
+ * Delete an import configuration by id.
+ *
+ * @return the deleted import configuration.
+ */
+ @DELETE
+ @Path("/{configId}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void deleteImportConfiguration(@PathParam("configId") String configId) {
+ importConfigurationService.delete(configId);
+ }
+
+
+
+ /**
+ * Save the given import configuration.
+ *
+ * @return the import configuration saved.
+ */
+ @POST
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public ImportConfiguration saveImportConfiguration(ImportConfiguration importConfiguration) {
+ ImportConfiguration importConfigSaved = importConfigurationService.save(importConfiguration);
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ try {
+ HttpPut httpPut = new HttpPut("http://localhost:8181/importConfigAdmin/");
+ StringEntity input = new StringEntity(new ObjectMapper().writeValueAsString(importConfigSaved));
+ input.setContentType(MediaType.APPLICATION_JSON);
+ httpPut.setEntity(input);
+
+ HttpResponse response = httpClient.execute(httpPut);
+
+ if (response.getStatusLine().getStatusCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + response.getStatusLine().getStatusCode());
+ }
+ } catch (IOException e) {
+ logger.warn("Unable to update Camel route [{}]", importConfiguration.getItemId());
+ }
+ return importConfigSaved;
+ }
+
+ /**
+ * Save/Update the given import configuration.
+ * Prepare the file to be processed with Camel routes
+ * @return OK / NOK Http Code.
+ */
+ @POST
+ @Path("/oneshot")
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response processOneshotImportConfigurationCSV(@Multipart(value = "importConfigId") String importConfigId, @Multipart(value = "file") Attachment file) {
+ try {
+ java.nio.file.Path path = Paths.get(uploadDir+importConfigId+".csv");
+ Files.deleteIfExists(path);
+ InputStream in = file.getObject(InputStream.class);
+
+ Files.copy(in, path);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ return Response.serverError().build();
+ }
+ return Response.ok().build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/router/router-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/router/router-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/router/router-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 0000000..a5cf1be
--- /dev/null
+++ b/router/router-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,72 @@
+<?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:cxf="http://cxf.apache.org/blueprint/core" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
+ 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
+ http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
+ http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
+ http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd">
+ <cm:property-placeholder persistent-id="org.apache.unomi.router" update-strategy="reload">
+ <cm:default-properties>
+ <cm:property name="import.oneshot.uploadDir" value="/tmp/oneshot_import_configs/"/>
+ </cm:default-properties>
+ </cm:property-placeholder>
+
+ <cxf:bus id="cxsServiceBus">
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <bean id="cors-filter" class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/>
+ <bean id="jacksonMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
+ <bean id="json-provider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
+ <argument index="0" ref="jacksonMapper" type="com.fasterxml.jackson.databind.ObjectMapper"/>
+ </bean>
+ <bean id="jaas-filter" class="org.apache.cxf.jaxrs.security.JAASAuthenticationFilter">
+ <!-- Name of the JAAS Context -->
+ <property name="contextName" value="karaf"/>
+ <!-- Hint to the filter on how to have Principals representing users and roles separated
+ while initializing a SecurityContext -->
+ <property name="rolePrefix" value="ROLE_"/>
+ <property name="realmName" value="cxs"/>
+ </bean>
+
+ <jaxrs:server address="/importConfiguration" id="restImportConfigurationService">
+ <jaxrs:providers>
+ <ref component-id="json-provider"/>
+ <ref component-id="cors-filter"/>
+ <ref component-id="jaas-filter"/>
+ </jaxrs:providers>
+
+ <jaxrs:serviceBeans>
+ <ref component-id="importConfigurationServiceEndPoint"/>
+ </jaxrs:serviceBeans>
+ </jaxrs:server>
+
+ <reference id="importConfigurationService" interface="org.apache.unomi.router.api.services.ImportConfigurationService"/>
+
+ <bean id="importConfigurationServiceEndPoint" class="org.apache.unomi.router.rest.ImportConfigurationServiceEndPoint">
+ <property name="importConfigurationService" ref="importConfigurationService"/>
+ <property name="uploadDir" value="${import.oneshot.uploadDir}"/>
+ </bean>
+
+</blueprint>
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/router/router-service/pom.xml
----------------------------------------------------------------------
diff --git a/router/router-service/pom.xml b/router/router-service/pom.xml
new file mode 100644
index 0000000..750cd1e
--- /dev/null
+++ b/router/router-service/pom.xml
@@ -0,0 +1,104 @@
+<?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>
+ <artifactId>unomi-router</artifactId>
+ <groupId>org.apache.unomi</groupId>
+ <version>1.2.0-incubating-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>unomi-router-service</artifactId>
+ <name>Apache Unomi :: Extensions :: Router :: Services</name>
+ <description>Router Services</description>
+ <packaging>bundle</packaging>
+
+ <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>
+ <Import-Package>
+ sun.misc;resolution:=optional,
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <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-router-api</artifactId>
+ <version>${project.version}</version>
+ <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>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/router/router-service/src/main/java/org/apache/unomi/router/services/ImportConfigurationServiceImpl.java
----------------------------------------------------------------------
diff --git a/router/router-service/src/main/java/org/apache/unomi/router/services/ImportConfigurationServiceImpl.java b/router/router-service/src/main/java/org/apache/unomi/router/services/ImportConfigurationServiceImpl.java
new file mode 100644
index 0000000..a4f6131
--- /dev/null
+++ b/router/router-service/src/main/java/org/apache/unomi/router/services/ImportConfigurationServiceImpl.java
@@ -0,0 +1,114 @@
+/*
+ * 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.router.services;
+
+import org.apache.unomi.router.api.ImportConfiguration;
+import org.apache.unomi.router.api.services.ImportConfigurationService;
+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.util.List;
+import java.util.UUID;
+
+/**
+ * Created by amidani on 28/04/2017.
+ */
+public class ImportConfigurationServiceImpl implements ImportConfigurationService,SynchronousBundleListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(ImportConfigurationServiceImpl.class.getName());
+
+ private BundleContext bundleContext;
+ private PersistenceService persistenceService;
+
+ public ImportConfigurationServiceImpl() {
+ logger.info("Initializing import configuration service...");
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void setPersistenceService(PersistenceService persistenceService) {
+ this.persistenceService = persistenceService;
+ }
+
+ public void postConstruct() {
+ logger.debug("postConstruct {" + bundleContext.getBundle() + "}");
+
+ processBundleStartup(bundleContext);
+ for (Bundle bundle : bundleContext.getBundles()) {
+ if (bundle.getBundleContext() != null) {
+ processBundleStartup(bundle.getBundleContext());
+ }
+ }
+ bundleContext.addBundleListener(this);
+ logger.info("Import configuration service initialized.");
+ }
+
+ public void preDestroy() {
+ bundleContext.removeBundleListener(this);
+ logger.info("Import configuration service shutdown.");
+ }
+
+ private void processBundleStartup(BundleContext bundleContext) {
+ if (bundleContext == null) {
+ return;
+ }
+ }
+
+ private void processBundleStop(BundleContext bundleContext) {
+ }
+
+
+ @Override
+ public List<ImportConfiguration> getImportConfigurations() {
+ return persistenceService.getAllItems(ImportConfiguration.class);
+ }
+
+ @Override
+ public ImportConfiguration load(String configId) {
+ return persistenceService.load(configId, ImportConfiguration.class);
+ }
+
+ @Override
+ public ImportConfiguration save(ImportConfiguration importConfiguration) {
+ if (importConfiguration.getItemId() == null) {
+ importConfiguration.setItemId(UUID.randomUUID().toString());
+ }
+ if(persistenceService.save(importConfiguration)) {
+
+ }
+
+ return persistenceService.load(importConfiguration.getItemId(), ImportConfiguration.class);
+ }
+
+ @Override
+ public void delete(String configId) {
+ persistenceService.remove(configId, ImportConfiguration.class);
+ }
+
+ @Override
+ public void bundleChanged(BundleEvent bundleEvent) {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/router/router-service/src/main/java/org/apache/unomi/router/services/ProfileImportServiceImpl.java
----------------------------------------------------------------------
diff --git a/router/router-service/src/main/java/org/apache/unomi/router/services/ProfileImportServiceImpl.java b/router/router-service/src/main/java/org/apache/unomi/router/services/ProfileImportServiceImpl.java
new file mode 100644
index 0000000..8097953
--- /dev/null
+++ b/router/router-service/src/main/java/org/apache/unomi/router/services/ProfileImportServiceImpl.java
@@ -0,0 +1,122 @@
+/*
+ * 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.router.services;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.unomi.api.Profile;
+import org.apache.unomi.api.services.EventListenerService;
+import org.apache.unomi.persistence.spi.PersistenceService;
+import org.apache.unomi.router.api.ProfileToImport;
+import org.apache.unomi.router.api.services.ProfileImportService;
+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.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+/**
+ * Created by amidani on 18/05/2017.
+ */
+public class ProfileImportServiceImpl implements ProfileImportService, SynchronousBundleListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(ProfileImportServiceImpl.class.getName());
+
+ private PersistenceService persistenceService;
+
+ private BundleContext bundleContext;
+
+ public void setPersistenceService(PersistenceService persistenceService) {
+ this.persistenceService = persistenceService;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void postConstruct() {
+ logger.debug("postConstruct {" + bundleContext.getBundle() + "}");
+
+ processBundleStartup(bundleContext);
+ for (Bundle bundle : bundleContext.getBundles()) {
+ if (bundle.getBundleContext() != null) {
+ processBundleStartup(bundle.getBundleContext());
+ }
+ }
+ bundleContext.addBundleListener(this);
+ logger.info("Import configuration service initialized.");
+ }
+
+ public void preDestroy() {
+ bundleContext.removeBundleListener(this);
+ logger.info("Import configuration service shutdown.");
+ }
+
+ private void processBundleStartup(BundleContext bundleContext) {
+ if (bundleContext == null) {
+ return;
+ }
+ }
+
+ private void processBundleStop(BundleContext bundleContext) {
+ }
+
+
+ public boolean saveMergeDeleteImportedProfile(ProfileToImport profileToImport) throws InvocationTargetException, IllegalAccessException {
+ logger.info("Importing profile: {}, {}", profileToImport.getProperties().get("firstName"), profileToImport.getProperties().get("lastName"));
+ Profile existingProfile = new Profile();
+ List<Profile> existingProfiles = persistenceService.query("properties."+profileToImport.getMergingProperty(), (String)profileToImport.getProperties().get(profileToImport.getMergingProperty()), null, Profile.class);
+ logger.info("Query existing profile with mergingProperty: {}", profileToImport.getMergingProperty());
+ logger.info("Found: {}", existingProfiles.size());
+
+ //Profile already exist, and import config allow to overwrite profiles
+ if(existingProfiles.size() == 1) {
+ existingProfile = existingProfiles.get(0);
+ if(profileToImport.isProfileToDelete()) {
+ logger.info("Profile is to delete!");
+ persistenceService.remove(existingProfile.getItemId(), Profile.class);
+ return true;
+ }
+ List<String> propertiesToOverwrite = profileToImport.getPropertiesToOverwrite();
+ if(profileToImport.isOverwriteExistingProfiles() && propertiesToOverwrite!=null && propertiesToOverwrite.size() > 0) { // We overwrite only properties marked to overwrite
+ logger.info("Properties to overwrite: {}", propertiesToOverwrite);
+ for(String propName : propertiesToOverwrite) {
+ existingProfile.getProperties().put(propName, profileToImport.getProperties().get(propName));
+ }
+ } else { //If no property is marked to overwrite we replace the whole properties map
+ logger.info("Overwrite all properties");
+ existingProfile.setProperties(profileToImport.getProperties());
+ }
+ } else if(existingProfiles.size() == 0) {
+ logger.info("New profile to add...");
+ BeanUtils.copyProperties(existingProfile, profileToImport);
+ } else {
+ logger.warn("{} occurences found for profile with {} = {}. Profile import is skipped", existingProfiles.size(),
+ profileToImport.getMergingProperty(), profileToImport.getProperties().get("firstName"));
+ }
+ logger.info("-------------------------------------");
+ return persistenceService.save(existingProfile);
+ }
+
+ @Override
+ public void bundleChanged(BundleEvent bundleEvent) {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/router/router-service/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/router/router-service/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/router/router-service/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 0000000..61200f2
--- /dev/null
+++ b/router/router-service/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,39 @@
+<?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="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">
+
+ <reference id="persistenceService" interface="org.apache.unomi.persistence.spi.PersistenceService"/>
+
+ <bean id="importConfigurationServiceImpl" class="org.apache.unomi.router.services.ImportConfigurationServiceImpl"
+ init-method="postConstruct" destroy-method="preDestroy">
+ <property name="persistenceService" ref="persistenceService"/>
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ </bean>
+ <service id="importConfigurationService" ref="importConfigurationServiceImpl" auto-export="interfaces"/>
+
+ <bean id="profileImportServiceImpl" class="org.apache.unomi.router.services.ProfileImportServiceImpl"
+ init-method="postConstruct" destroy-method="preDestroy">
+ <property name="persistenceService" ref="persistenceService"/>
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ </bean>
+ <service id="profileImportService" ref="profileImportServiceImpl" auto-export="interfaces"/>
+
+</blueprint>
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/samples/trainingplugin.zip
----------------------------------------------------------------------
diff --git a/samples/trainingplugin.zip b/samples/trainingplugin.zip
new file mode 100644
index 0000000..1226fc1
Binary files /dev/null and b/samples/trainingplugin.zip differ
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/samples/trainingplugin/pom.xml
----------------------------------------------------------------------
diff --git a/samples/trainingplugin/pom.xml b/samples/trainingplugin/pom.xml
new file mode 100644
index 0000000..34711a7
--- /dev/null
+++ b/samples/trainingplugin/pom.xml
@@ -0,0 +1,55 @@
+<?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>
+ <artifactId>samples</artifactId>
+ <groupId>org.apache.unomi</groupId>
+ <version>1.2.0-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>training-plugin</artifactId>
+ <name>Apache Unomi :: Samples :: Training plugin</name>
+ <packaging>bundle</packaging>
+ <description>This is a simple Apache Unomi plugin.</description>
+ <modelVersion>4.0.0</modelVersion>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.unomi</groupId>
+ <artifactId>unomi-api</artifactId>
+ <version>1.2.0-incubating-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/samples/trainingplugin/src/main/java/org/apache/unomi/training/TrainedNotificationAction.java
----------------------------------------------------------------------
diff --git a/samples/trainingplugin/src/main/java/org/apache/unomi/training/TrainedNotificationAction.java b/samples/trainingplugin/src/main/java/org/apache/unomi/training/TrainedNotificationAction.java
new file mode 100644
index 0000000..7f64cbd
--- /dev/null
+++ b/samples/trainingplugin/src/main/java/org/apache/unomi/training/TrainedNotificationAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.training;
+
+import org.apache.unomi.api.Event;
+import org.apache.unomi.api.Metadata;
+import org.apache.unomi.api.Profile;
+import org.apache.unomi.api.PropertyType;
+import org.apache.unomi.api.actions.Action;
+import org.apache.unomi.api.actions.ActionExecutor;
+import org.apache.unomi.api.services.EventService;
+import org.apache.unomi.api.services.ProfileService;
+
+import java.util.Collections;
+
+/**
+ * Created by amidani on 11/04/2017.
+ */
+public class TrainedNotificationAction implements ActionExecutor {
+
+ private static final String TRAINED_NB_PROPERTY = "trained";
+ private static final String TARGET = "profiles";
+
+ private ProfileService service;
+
+ public void setProfileService(ProfileService service) {
+ this.service = service;
+ }
+
+ @Override
+ public int execute(Action action, Event event) {
+ final Profile profile = event.getProfile();
+ Integer trained = (Integer) profile.getProperty(TRAINED_NB_PROPERTY);
+
+ if (trained == null) {
+ // create trained flag property type
+ PropertyType propertyType = new PropertyType(new Metadata(event.getScope(), TRAINED_NB_PROPERTY, TRAINED_NB_PROPERTY, "Am I trained"));
+ propertyType.setValueTypeId("boolean");
+ propertyType.setTagIds(Collections.singleton("training"));
+ propertyType.setTarget(TARGET);
+ service.setPropertyType(propertyType);
+ }
+
+ profile.setProperty(TRAINED_NB_PROPERTY, true);
+ return EventService.PROFILE_UPDATED;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/samples/trainingplugin/src/main/resources/META-INF/cxs/actions/trainingNotifAction.json
----------------------------------------------------------------------
diff --git a/samples/trainingplugin/src/main/resources/META-INF/cxs/actions/trainingNotifAction.json b/samples/trainingplugin/src/main/resources/META-INF/cxs/actions/trainingNotifAction.json
new file mode 100644
index 0000000..2ac9763
--- /dev/null
+++ b/samples/trainingplugin/src/main/resources/META-INF/cxs/actions/trainingNotifAction.json
@@ -0,0 +1,13 @@
+{
+ "metadata": {
+ "id": "trainingNotifAction",
+ "name": "Training Action",
+ "description": "",
+ "tags": [
+ "event"
+ ],
+ "readOnly": true
+ },
+ "actionExecutor": "training",
+ "parameters": []
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/samples/trainingplugin/src/main/resources/META-INF/cxs/rules/trainedNotification.json
----------------------------------------------------------------------
diff --git a/samples/trainingplugin/src/main/resources/META-INF/cxs/rules/trainedNotification.json b/samples/trainingplugin/src/main/resources/META-INF/cxs/rules/trainedNotification.json
new file mode 100644
index 0000000..e098e3e
--- /dev/null
+++ b/samples/trainingplugin/src/main/resources/META-INF/cxs/rules/trainedNotification.json
@@ -0,0 +1,20 @@
+{
+ "metadata": {
+ "id": "smp:trainedRule",
+ "name": "Trained",
+ "description": "..."
+ },
+ "raiseEventOnlyOnceForSession": false,
+ "condition": {
+ "type": "eventTypeCondition",
+ "parameterValues": {
+ "eventTypeId": "trainingEvent"
+ }
+ },
+ "actions": [
+ {
+ "type": "trainingNotifAction",
+ "parameterValues": {}
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/5fa45c29/samples/trainingplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/samples/trainingplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/samples/trainingplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 0000000..41764cc
--- /dev/null
+++ b/samples/trainingplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,34 @@
+<?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="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">
+
+ <reference id="profileService" interface="org.apache.unomi.api.services.ProfileService"/>
+
+ <!-- Action executor -->
+ <service id="trainingNotifAction" auto-export="interfaces">
+ <service-properties>
+ <entry key="actionExecutorId" value="training"/>
+ </service-properties>
+ <bean class="org.apache.unomi.training.TrainedNotificationAction">
+ <property name="profileService" ref="profileService"/>
+ </bean>
+ </service>
+</blueprint>