http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/extensions/privacy-extension/rest/src/main/java/org/oasis_open/contextserver/privacy/rest/PrivacyServiceEndPoint.java ---------------------------------------------------------------------- diff --git a/extensions/privacy-extension/rest/src/main/java/org/oasis_open/contextserver/privacy/rest/PrivacyServiceEndPoint.java b/extensions/privacy-extension/rest/src/main/java/org/oasis_open/contextserver/privacy/rest/PrivacyServiceEndPoint.java deleted file mode 100644 index 205d878..0000000 --- a/extensions/privacy-extension/rest/src/main/java/org/oasis_open/contextserver/privacy/rest/PrivacyServiceEndPoint.java +++ /dev/null @@ -1,121 +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.oasis_open.contextserver.privacy.rest; - -import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing; -import org.oasis_open.contextserver.api.ServerInfo; -import org.oasis_open.contextserver.api.services.PrivacyService; - -import javax.jws.WebMethod; -import javax.jws.WebService; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.NewCookie; -import javax.ws.rs.core.Response; -import java.util.List; - -/** - * Created by loom on 10.09.15. - */ -@WebService -@Produces(MediaType.APPLICATION_JSON) -@CrossOriginResourceSharing( - allowAllOrigins = true, - allowCredentials = true -) -public class PrivacyServiceEndPoint { - - private PrivacyService privacyService; - - @WebMethod(exclude = true) - public void setPrivacyService(PrivacyService privacyService) { - this.privacyService = privacyService; - } - - @GET - @Path("/info") - public ServerInfo getServerInfo() { - return privacyService.getServerInfo(); - } - - @DELETE - @Path("/profiles/{profileId}") - public Response deleteProfileData(@PathParam("profileId") String profileId, @QueryParam("withData") @DefaultValue("false") boolean withData) { - if (withData) { - privacyService.deleteProfileData(profileId); - } else { - privacyService.deleteProfile(profileId); - } - return Response.ok().build(); - } - - @POST - @Path("/profiles/{profileId}/anonymize") - public Response anonymizeBrowsingData(@PathParam("profileId") String profileId) { - String newProfileId = privacyService.anonymizeBrowsingData(profileId); - if (!profileId.equals(newProfileId)) { - return Response.ok() - .cookie(new NewCookie("context-profile-id", newProfileId, "/", null, null, NewCookie.DEFAULT_MAX_AGE, false)) - .entity(newProfileId) - .build(); - } - return Response.serverError().build(); - } - - @GET - @Path("/profiles/{profileId}/anonymous") - public Boolean isAnonymous(@PathParam("profileId") String profileId) { - return privacyService.isAnonymous(profileId); - } - - @POST - @Path("/profiles/{profileId}/anonymous") - public Response activateAnonymousSurfing(@PathParam("profileId") String profileId) { - privacyService.setAnonymous(profileId, true); - return Response.ok().build(); - } - - @DELETE - @Path("/profiles/{profileId}/anonymous") - public Response deactivateAnonymousSurfing(@PathParam("profileId") String profileId) { - privacyService.setAnonymous(profileId, false); - return Response.ok().build(); - } - - @GET - @Path("/profiles/{profileId}/eventFilters") - public List<String> getEventFilters(@PathParam("profileId") String profileId) { - return privacyService.getFilteredEventTypes(profileId); - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Path("/profiles/{profileId}/eventFilters") - public Response setEventFilters(@PathParam("profileId") String profileId, List<String> eventFilters) { - privacyService.setFilteredEventTypes(profileId, eventFilters); - return Response.ok().build(); - } - - @DELETE - @Path("/profiles/{profileId}/properties/{propertyName}") - public Response removeProperty(@PathParam("profileId") String profileId, @PathParam("propertyName") String propertyName) { - privacyService.removeProperty(profileId, propertyName); - return Response.ok().build(); - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/extensions/privacy-extension/rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml ---------------------------------------------------------------------- diff --git a/extensions/privacy-extension/rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/extensions/privacy-extension/rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml index e6ccb0e..c7089e6 100644 --- a/extensions/privacy-extension/rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/extensions/privacy-extension/rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -30,7 +30,7 @@ </cxf:bus> <bean id="cors-filter" class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/> - <bean id="jacksonMapper" class="org.oasis_open.contextserver.persistence.spi.CustomObjectMapper"/> + <bean id="jacksonMapper" class="org.apache.unomi.persistence.spi.CustomObjectMapper"/> <bean id="jaxb-provider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"> <argument index="0" ref="jacksonMapper" type="com.fasterxml.jackson.databind.ObjectMapper "/> <argument index="1" type="com.fasterxml.jackson.jaxrs.cfg.Annotations[]"> @@ -65,9 +65,9 @@ </jaxrs:serviceBeans> </jaxrs:server> - <reference id="privacyService" interface="org.oasis_open.contextserver.api.services.PrivacyService"/> + <reference id="privacyService" interface="org.apache.unomi.api.services.PrivacyService"/> - <bean id="privacyServiceEndPoint" class="org.oasis_open.contextserver.privacy.rest.PrivacyServiceEndPoint"> + <bean id="privacyServiceEndPoint" class="org.apache.unomi.privacy.rest.PrivacyServiceEndPoint"> <property name="privacyService" ref="privacyService"/> </bean> </blueprint> http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/extensions/privacy-extension/services/src/main/java/org/apache/unomi/privacy/internal/PrivacyServiceImpl.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..9ba5ddd --- /dev/null +++ b/extensions/privacy-extension/services/src/main/java/org/apache/unomi/privacy/internal/PrivacyServiceImpl.java @@ -0,0 +1,207 @@ +/* + * 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.privacy.internal; + +import org.apache.unomi.api.*; +import org.apache.unomi.api.conditions.Condition; +import org.apache.unomi.api.services.DefinitionsService; +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.persistence.spi.PersistenceService; +import org.apache.unomi.persistence.spi.aggregate.TermsAggregate; + +import java.util.*; + +/** + * Privacy service implementation + */ +public class PrivacyServiceImpl implements PrivacyService { + + private PersistenceService persistenceService; + private DefinitionsService definitionsService; + private ProfileService profileService; + private EventService eventService; + + public void setPersistenceService(PersistenceService persistenceService) { + this.persistenceService = persistenceService; + } + + public void setDefinitionsService(DefinitionsService definitionsService) { + this.definitionsService = definitionsService; + } + + public void setProfileService(ProfileService profileService) { + this.profileService = profileService; + } + + public void setEventService(EventService eventService) { + this.eventService = eventService; + } + + @Override + public ServerInfo getServerInfo() { + ServerInfo serverInfo = new ServerInfo(); + serverInfo.setServerIdentifier("Apache Unomi"); + serverInfo.setServerVersion("2.0.0.incubating-SNAPSHOT"); + + // let's retrieve all the event types the server has seen. + Map<String,Long> eventTypeCounts = persistenceService.aggregateQuery(null, new TermsAggregate("eventType"), Event.ITEM_TYPE); + List<EventInfo> eventTypes = new ArrayList<EventInfo>(); + for (Map.Entry<String,Long> eventTypeEntry : eventTypeCounts.entrySet()) { + EventInfo eventInfo = new EventInfo(); + eventInfo.setName(eventTypeEntry.getKey()); + eventInfo.setOccurences(eventTypeEntry.getValue()); + eventTypes.add(eventInfo); + } + serverInfo.setEventTypes(eventTypes); + + serverInfo.setCapabilities(new HashMap<String,String>()); + return serverInfo; + } + + @Override + public Boolean deleteProfile(String profileId) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return false; + } + // we simply overwrite the existing profile with an empty one. + Profile emptyProfile = new Profile(profileId); + profileService.save(emptyProfile); + return true; + } + + @Override + public String anonymizeBrowsingData(String profileId) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return profileId; + } + Profile newProfile = new Profile(UUID.randomUUID().toString()); + // first we copy all the profile data to the new Profile + newProfile.setMergedWith(profile.getMergedWith()); + newProfile.setProperties(profile.getProperties()); + newProfile.setScores(profile.getScores()); + newProfile.setSegments(profile.getSegments()); + newProfile.setSystemProperties(profile.getSystemProperties()); + newProfile.setScope(profile.getScope()); + profileService.save(newProfile); + // then we clear the old profile of all data + profile.setMergedWith(null); + profile.setProperties(new HashMap<String, Object>()); + profile.setScores(new HashMap<String, Integer>()); + profile.setSegments(new HashSet<String>()); + profile.setSystemProperties(new HashMap<String, Object>()); + profile.setScope(null); + profileService.save(profile); + return newProfile.getItemId(); + } + + @Override + public Boolean deleteProfileData(String profileId) { + Condition eventPropertyCondition = new Condition(definitionsService.getConditionType("eventPropertyCondition")); + eventPropertyCondition.setParameter("propertyName", "profileId"); + eventPropertyCondition.setParameter("propertyValue", profileId); + eventPropertyCondition.setParameter("comparisonOperator", "equals"); + persistenceService.removeByQuery(eventPropertyCondition, Event.class); + + Condition sessionPropertyCondition = new Condition(definitionsService.getConditionType("sessionPropertyCondition")); + sessionPropertyCondition.setParameter("propertyName", "profileId"); + sessionPropertyCondition.setParameter("propertyValue", profileId); + sessionPropertyCondition.setParameter("comparisonOperator", "equals"); + persistenceService.removeByQuery(sessionPropertyCondition, Session.class); + + profileService.delete(profileId, false); + return true; + } + + @Override + public Boolean setAnonymous(String profileId, boolean anonymous) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return false; + } + profile.setProperty("anonymous", anonymous); + profileService.save(profile); + return true; + } + + public Boolean isAnonymous(String profileId) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return null; + } + Boolean anonymous = (Boolean) profile.getProperty("anonymous"); + return anonymous; + } + + @Override + public List<String> getFilteredEventTypes(String profileId) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return new ArrayList<String>(); + } + return (List<String>) profile.getProperty("filteredEventTypes"); + } + + @Override + public Boolean setFilteredEventTypes(String profileId, List<String> eventTypes) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return null; + } + profile.setProperty("filteredEventTypes", eventTypes); + profileService.save(profile); + return true; + } + + @Override + public List<String> getDeniedProperties(String profileId) { + return null; + } + + @Override + public Boolean setDeniedProperties(String profileId, List<String> propertyNames) { + return null; + } + + @Override + public List<String> getDeniedPropertyDistribution(String profileId) { + return null; + } + + @Override + public Boolean setDeniedPropertyDistribution(String profileId, List<String> propertyNames) { + return null; + } + + @Override + public Boolean removeProperty(String profileId, String propertyName) { + Profile profile = profileService.load(profileId); + if (profile == null) { + return null; + } + if (!profile.getProperties().containsKey(propertyName)) { + return false; + } + Object propertyValue = profile.getProperties().remove(propertyName); + profileService.save(profile); + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/extensions/privacy-extension/services/src/main/java/org/oasis_open/contextserver/privacy/internal/PrivacyServiceImpl.java ---------------------------------------------------------------------- diff --git a/extensions/privacy-extension/services/src/main/java/org/oasis_open/contextserver/privacy/internal/PrivacyServiceImpl.java b/extensions/privacy-extension/services/src/main/java/org/oasis_open/contextserver/privacy/internal/PrivacyServiceImpl.java deleted file mode 100644 index 51f0849..0000000 --- a/extensions/privacy-extension/services/src/main/java/org/oasis_open/contextserver/privacy/internal/PrivacyServiceImpl.java +++ /dev/null @@ -1,207 +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.oasis_open.contextserver.privacy.internal; - -import org.oasis_open.contextserver.api.*; -import org.oasis_open.contextserver.api.conditions.Condition; -import org.oasis_open.contextserver.api.services.DefinitionsService; -import org.oasis_open.contextserver.api.services.EventService; -import org.oasis_open.contextserver.api.services.PrivacyService; -import org.oasis_open.contextserver.api.services.ProfileService; -import org.oasis_open.contextserver.persistence.spi.PersistenceService; -import org.oasis_open.contextserver.persistence.spi.aggregate.TermsAggregate; - -import java.util.*; - -/** - * Created by loom on 10.09.15. - */ -public class PrivacyServiceImpl implements PrivacyService { - - private PersistenceService persistenceService; - private DefinitionsService definitionsService; - private ProfileService profileService; - private EventService eventService; - - public void setPersistenceService(PersistenceService persistenceService) { - this.persistenceService = persistenceService; - } - - public void setDefinitionsService(DefinitionsService definitionsService) { - this.definitionsService = definitionsService; - } - - public void setProfileService(ProfileService profileService) { - this.profileService = profileService; - } - - public void setEventService(EventService eventService) { - this.eventService = eventService; - } - - @Override - public ServerInfo getServerInfo() { - ServerInfo serverInfo = new ServerInfo(); - serverInfo.setServerIdentifier("Apache Unomi"); - serverInfo.setServerVersion("2.0.0.incubating-SNAPSHOT"); - - // let's retrieve all the event types the server has seen. - Map<String,Long> eventTypeCounts = persistenceService.aggregateQuery(null, new TermsAggregate("eventType"), Event.ITEM_TYPE); - List<EventInfo> eventTypes = new ArrayList<EventInfo>(); - for (Map.Entry<String,Long> eventTypeEntry : eventTypeCounts.entrySet()) { - EventInfo eventInfo = new EventInfo(); - eventInfo.setName(eventTypeEntry.getKey()); - eventInfo.setOccurences(eventTypeEntry.getValue()); - eventTypes.add(eventInfo); - } - serverInfo.setEventTypes(eventTypes); - - serverInfo.setCapabilities(new HashMap<String,String>()); - return serverInfo; - } - - @Override - public Boolean deleteProfile(String profileId) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return false; - } - // we simply overwrite the existing profile with an empty one. - Profile emptyProfile = new Profile(profileId); - profileService.save(emptyProfile); - return true; - } - - @Override - public String anonymizeBrowsingData(String profileId) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return profileId; - } - Profile newProfile = new Profile(UUID.randomUUID().toString()); - // first we copy all the profile data to the new Profile - newProfile.setMergedWith(profile.getMergedWith()); - newProfile.setProperties(profile.getProperties()); - newProfile.setScores(profile.getScores()); - newProfile.setSegments(profile.getSegments()); - newProfile.setSystemProperties(profile.getSystemProperties()); - newProfile.setScope(profile.getScope()); - profileService.save(newProfile); - // then we clear the old profile of all data - profile.setMergedWith(null); - profile.setProperties(new HashMap<String, Object>()); - profile.setScores(new HashMap<String, Integer>()); - profile.setSegments(new HashSet<String>()); - profile.setSystemProperties(new HashMap<String, Object>()); - profile.setScope(null); - profileService.save(profile); - return newProfile.getItemId(); - } - - @Override - public Boolean deleteProfileData(String profileId) { - Condition eventPropertyCondition = new Condition(definitionsService.getConditionType("eventPropertyCondition")); - eventPropertyCondition.setParameter("propertyName", "profileId"); - eventPropertyCondition.setParameter("propertyValue", profileId); - eventPropertyCondition.setParameter("comparisonOperator", "equals"); - persistenceService.removeByQuery(eventPropertyCondition, Event.class); - - Condition sessionPropertyCondition = new Condition(definitionsService.getConditionType("sessionPropertyCondition")); - sessionPropertyCondition.setParameter("propertyName", "profileId"); - sessionPropertyCondition.setParameter("propertyValue", profileId); - sessionPropertyCondition.setParameter("comparisonOperator", "equals"); - persistenceService.removeByQuery(sessionPropertyCondition, Session.class); - - profileService.delete(profileId, false); - return true; - } - - @Override - public Boolean setAnonymous(String profileId, boolean anonymous) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return false; - } - profile.setProperty("anonymous", anonymous); - profileService.save(profile); - return true; - } - - public Boolean isAnonymous(String profileId) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return null; - } - Boolean anonymous = (Boolean) profile.getProperty("anonymous"); - return anonymous; - } - - @Override - public List<String> getFilteredEventTypes(String profileId) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return new ArrayList<String>(); - } - return (List<String>) profile.getProperty("filteredEventTypes"); - } - - @Override - public Boolean setFilteredEventTypes(String profileId, List<String> eventTypes) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return null; - } - profile.setProperty("filteredEventTypes", eventTypes); - profileService.save(profile); - return true; - } - - @Override - public List<String> getDeniedProperties(String profileId) { - return null; - } - - @Override - public Boolean setDeniedProperties(String profileId, List<String> propertyNames) { - return null; - } - - @Override - public List<String> getDeniedPropertyDistribution(String profileId) { - return null; - } - - @Override - public Boolean setDeniedPropertyDistribution(String profileId, List<String> propertyNames) { - return null; - } - - @Override - public Boolean removeProperty(String profileId, String propertyName) { - Profile profile = profileService.load(profileId); - if (profile == null) { - return null; - } - if (!profile.getProperties().containsKey(propertyName)) { - return false; - } - Object propertyValue = profile.getProperties().remove(propertyName); - profileService.save(profile); - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/extensions/privacy-extension/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml ---------------------------------------------------------------------- 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 d5c751d..64b8db2 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 @@ -20,17 +20,17 @@ 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.oasis_open.contextserver.persistence.spi.PersistenceService"/> + interface="org.apache.unomi.persistence.spi.PersistenceService"/> - <reference id="definitionsService" interface="org.oasis_open.contextserver.api.services.DefinitionsService"/> + <reference id="definitionsService" interface="org.apache.unomi.api.services.DefinitionsService"/> - <reference id="eventService" interface="org.oasis_open.contextserver.api.services.EventService"/> + <reference id="eventService" interface="org.apache.unomi.api.services.EventService"/> - <reference id="profileService" interface="org.oasis_open.contextserver.api.services.ProfileService"/> + <reference id="profileService" interface="org.apache.unomi.api.services.ProfileService"/> <!-- Privacy service --> - <bean id="privacyServiceImpl" class="org.oasis_open.contextserver.privacy.internal.PrivacyServiceImpl"> + <bean id="privacyServiceImpl" class="org.apache.unomi.privacy.internal.PrivacyServiceImpl"> <property name="persistenceService" ref="persistenceService"/> <property name="definitionsService" ref="definitionsService"/> <property name="eventService" ref="eventService" /> http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/AllTests.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/AllTests.java b/itests/src/test/java/org/apache/unomi/itests/AllTests.java new file mode 100644 index 0000000..8f017ba --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/AllTests.java @@ -0,0 +1,37 @@ +/* + * 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.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Defines suite of test classes to run. + * + * @author Sergiy Shyrkov + */ +@RunWith(Suite.class) +@SuiteClasses({ + //BasicTest.class, + ConditionEvaluatorTest.class, + ConditionESQueryBuilderTest.class, + SegmentTest.class + }) +public class AllTests { +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/BaseTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseTest.java b/itests/src/test/java/org/apache/unomi/itests/BaseTest.java new file mode 100644 index 0000000..9db3d9b --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/BaseTest.java @@ -0,0 +1,100 @@ +/* + * 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.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; +import org.ops4j.pax.exam.options.MavenArtifactUrlReference; +import org.ops4j.pax.exam.options.MavenUrlReference; + +import java.io.File; + +import static org.ops4j.pax.exam.CoreOptions.*; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*; + +/** + * Base class for integration tests. + * + * @author kevan + */ +public abstract class BaseTest { + + protected static final String HTTP_PORT = "8181"; + + protected static final String URL = "http://localhost:" + HTTP_PORT; + + @Configuration + public Option[] config() { + MavenArtifactUrlReference karafUrl = maven() + .groupId("org.apache.karaf") + .artifactId("apache-karaf") + .version("3.0.2") + .type("tar.gz"); + + MavenUrlReference karafStandardRepo = maven() + .groupId("org.apache.karaf.features") + .artifactId("standard") + .classifier("features") + .type("xml") + .versionAsInProject(); + MavenUrlReference karafPaxWebRepo = maven() + .groupId("org.ops4j.pax.web") + .artifactId("pax-web-features") + .classifier("features") + .type("xml") + .versionAsInProject(); + MavenUrlReference karafCxfRepo = maven() + .groupId("org.apache.cxf.karaf") + .artifactId("apache-cxf") + .classifier("features") + .type("xml") + .versionAsInProject(); + MavenUrlReference contextServerRepo = maven() + .groupId("org.apache.unomi") + .artifactId("unomi-kar") + .classifier("features") + .type("xml") + .versionAsInProject(); + + return new Option[]{ + debugConfiguration("5005", false), + karafDistributionConfiguration() + .frameworkUrl(karafUrl) + .unpackDirectory(new File("target/exam")) + .useDeployFolder(false), +// keepRuntimeFolder(), + configureConsole().ignoreLocalConsole().ignoreRemoteShell(), + logLevel(LogLevel.INFO), +// editConfigurationFilePut("etc/org.ops4j.pax.web.cfg", "org.osgi.service.http.port", HTTP_PORT), +// systemProperty("org.osgi.service.http.port").value(HTTP_PORT), + features(karafPaxWebRepo, "war"), + features(karafCxfRepo, "cxf"), + features(karafStandardRepo, "openwebbeans"), + features(karafStandardRepo, "pax-cdi-web-openwebbeans"), + features(contextServerRepo, "unomi-kar"), + // we need to wrap the HttpComponents libraries ourselves since the OSGi bundles provided by the project are incorrect + wrappedBundle(mavenBundle("org.apache.httpcomponents", + "httpcore").versionAsInProject()), + wrappedBundle(mavenBundle("org.apache.httpcomponents", + "httpmime").versionAsInProject()), + wrappedBundle(mavenBundle("org.apache.httpcomponents", + "httpclient").versionAsInProject()) + }; + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/BasicTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/BasicTest.java b/itests/src/test/java/org/apache/unomi/itests/BasicTest.java new file mode 100644 index 0000000..7bfba87 --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/BasicTest.java @@ -0,0 +1,99 @@ +/* + * 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 com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.apache.unomi.api.ContextRequest; +import org.apache.unomi.api.ContextResponse; +import org.junit.Assert; +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 java.io.IOException; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerSuite.class) +public class BasicTest extends BaseTest{ + private static final String JSON_MYME_TYPE = "application/json"; + + private ObjectMapper objectMapper = new ObjectMapper(); + + @Test + public void testContextJS() throws IOException { + HttpUriRequest request = new HttpGet(URL + "/context.js?sessionId=aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d9"); + CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request); + // The underlying HTTP connection is still held by the response object + // to allow the response content to be streamed directly from the network socket. + // In order to ensure correct deallocation of system resources + // the profile MUST call CloseableHttpResponse#close() from a finally clause. + // Please note that if response content is not fully consumed the underlying + // connection cannot be safely re-used and will be shut down and discarded + // by the connection manager. + String responseContent = null; + try { + System.out.println(response.getStatusLine()); + HttpEntity entity = response.getEntity(); + // do something useful with the response body + // and ensure it is fully consumed + responseContent = EntityUtils.toString(entity); + } finally { + response.close(); + } + Assert.assertTrue("Response should contain context object", responseContent.contains("window.digitalData = window.digitalData || {};")); + // @todo we should check the validity of the context object, but this is rather complex since it would + // potentially require parsing the Javascript ! + } + + @Test + public void testContextJSON() throws IOException { + String sessionId = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d9"; + ContextRequest contextRequest = new ContextRequest(); +// contextRequest.setSource(new EventSource()); +// contextRequest.getSource().setId("af6f393a-a537-4586-991b-8521b9c7b05b"); + HttpPost request = new HttpPost(URL + "/context.json?sessionId=" + sessionId); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.create("application/json"))); + CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request); + + try { + // validate mimeType + String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType(); + Assert.assertEquals("Response content type should be " + JSON_MYME_TYPE, JSON_MYME_TYPE, mimeType); + + // validate context + ContextResponse context = TestUtils.retrieveResourceFromResponse(response, ContextResponse.class); + Assert.assertNotNull("Context should not be null", context); + Assert.assertNotNull("Context profileId should not be null", context.getProfileId()); + Assert.assertEquals("Context sessionId should be the same as the sessionId used to request the context", sessionId, context.getSessionId()); + } finally { + response.close(); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/ConditionBuilder.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ConditionBuilder.java b/itests/src/test/java/org/apache/unomi/itests/ConditionBuilder.java new file mode 100644 index 0000000..0fbffcd --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/ConditionBuilder.java @@ -0,0 +1,290 @@ +/* + * 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.unomi.api.conditions.Condition; +import org.apache.unomi.api.services.DefinitionsService; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; + +/** + * Utility class for building conditions + * + * @author Sergiy Shyrkov + */ +public class ConditionBuilder { + + private DefinitionsService definitionsService; + + /** + * Initializes an instance of this class. + * + * @param definitionsService an instance of the {@link DefinitionsService} + */ + public ConditionBuilder(DefinitionsService definitionsService) { + super(); + this.definitionsService = definitionsService; + } + + public CompoundCondition and(ConditionItem condition1, ConditionItem condition2) { + return new CompoundCondition(condition1, condition2, "and"); + } + + public NotCondition not(ConditionItem subCondition) { + return new NotCondition(subCondition); + } + + public CompoundCondition or(ConditionItem condition1, ConditionItem condition2) { + return new CompoundCondition(condition1, condition2, "or"); + } + + public PropertyCondition profileProperty(String propertyName) { + return new PropertyCondition("profilePropertyCondition", propertyName, definitionsService); + } + + public PropertyCondition property(String conditionTypeId, String propertyName) { + return new PropertyCondition(conditionTypeId, propertyName, definitionsService); + } + + public abstract class ComparisonCondition extends ConditionItem { + + ComparisonCondition(String conditionTypeId, DefinitionsService definitionsService) { + super(conditionTypeId, definitionsService); + } + + public ComparisonCondition all(String... values) { + return op("all").stringValues(values); + } + + public ComparisonCondition all(Date... values) { + return op("all").dateValues(values); + } + + public ComparisonCondition all(Integer... values) { + return op("all").integerValues(values); + } + + public ComparisonCondition contains(String value) { + return op("contains").stringValue(value); + } + + public ComparisonCondition endsWith(String value) { + return op("endsWith").stringValue(value); + } + + public ComparisonCondition equalTo(String value) { + return op("equals").stringValue(value); + } + + public ComparisonCondition equalTo(Date value) { + return op("equals").dateValue(value); + } + + public ComparisonCondition equalTo(Integer value) { + return op("equals").integerValue(value); + } + + public ComparisonCondition exists() { + return op("exists"); + } + + public ComparisonCondition greaterThan(Date value) { + return op("greaterThan").dateValue(value); + } + + public ComparisonCondition greaterThan(Integer value) { + return op("greaterThan").integerValue(value); + } + + public ComparisonCondition greaterThanOrEqualTo(Date value) { + return op("greaterThanOrEqualTo").dateValue(value); + } + + public ComparisonCondition greaterThanOrEqualTo(Integer value) { + return op("greaterThanOrEqualTo").integerValue(value); + } + + public ComparisonCondition in(String... values) { + return op("in").stringValues(values); + } + + public ComparisonCondition in(Date... values) { + return op("in").dateValues(values); + } + + public ComparisonCondition in(Integer... values) { + return op("in").integerValues(values); + } + + public ComparisonCondition lessThan(Date value) { + return op("lessThan").dateValue(value); + } + + public ComparisonCondition lessThan(Integer value) { + return op("lessThan").integerValue(value); + } + + public ComparisonCondition lessThanOrEqualTo(Date value) { + return op("lessThanOrEqualTo").dateValue(value); + } + + public ComparisonCondition lessThanOrEqualTo(Integer value) { + return op("lessThanOrEqualTo").integerValue(value); + } + + public ComparisonCondition between(Date lowerBound, Date upperBound) { + return op("between").dateValues(lowerBound, upperBound); + } + + public ComparisonCondition between(Integer lowerBound, Integer upperBound) { + return op("between").integerValues(lowerBound, upperBound); + } + + public ComparisonCondition matchesRegex(String value) { + return op("matchesRegex").stringValue(value); + } + + public ComparisonCondition missing() { + return op("missing"); + } + + public ComparisonCondition notEqualTo(String value) { + return op("notEquals").stringValue(value); + } + + public ComparisonCondition notEqualTo(Date value) { + return op("notEquals").dateValue(value); + } + + public ComparisonCondition notEqualTo(Integer value) { + return op("notEquals").integerValue(value); + } + + public ComparisonCondition notIn(String... values) { + return op("notIn").stringValues(values); + } + + public ComparisonCondition notIn(Date... values) { + return op("notIn").dateValues(values); + } + + public ComparisonCondition notIn(Integer... values) { + return op("notIn").integerValues(values); + } + + private ComparisonCondition op(String op) { + return parameter("comparisonOperator", op); + } + + @Override + public ComparisonCondition parameter(String name, Object value) { + return (ComparisonCondition) super.parameter(name, value); + } + + public ComparisonCondition parameter(String name, Object... values) { + return (ComparisonCondition) super.parameter(name, values); + } + + public ComparisonCondition startsWith(String value) { + return op("startsWith").stringValue(value); + } + + private ComparisonCondition stringValue(String value) { + return parameter("propertyValue", value); + } + + private ComparisonCondition integerValue(Integer value) { + return parameter("propertyValueInteger", value); + } + + private ComparisonCondition dateValue(Date value) { + return parameter("propertyValueDate", value); + } + + private ComparisonCondition stringValues(String... values) { + return parameter("propertyValues", values != null ? Arrays.asList(values) : null); + } + + private ComparisonCondition integerValues(Integer... values) { + return parameter("propertyValuesInteger", values != null ? Arrays.asList(values) : null); + } + + private ComparisonCondition dateValues(Date... values) { + return parameter("propertyValuesDate", values != null ? Arrays.asList(values) : null); + } + } + + public class CompoundCondition extends ConditionItem { + + CompoundCondition(ConditionItem condition1, ConditionItem condition2, String operator) { + super("booleanCondition", condition1.definitionsService); + parameter("operator", operator); + ArrayList<Condition> subConditions = new ArrayList<Condition>(2); + subConditions.add(condition1.build()); + subConditions.add(condition2.build()); + parameter("subConditions", subConditions); + } + } + + public abstract class ConditionItem { + + protected Condition condition; + + private DefinitionsService definitionsService; + + ConditionItem(String conditionTypeId, DefinitionsService definitionsService) { + this.definitionsService = definitionsService; + condition = new Condition( + this.definitionsService.getConditionType(conditionTypeId)); + } + + public Condition build() { + return condition; + } + + public ConditionItem parameter(String name, Object value) { + condition.setParameter(name, value); + return this; + } + + public ConditionItem parameter(String name, Object... values) { + condition.setParameter(name, values != null ? Arrays.asList(values) : null); + return this; + } + + } + + public class NotCondition extends ConditionItem { + + NotCondition(ConditionItem subCondition) { + super("notCondition", subCondition.definitionsService); + parameter("subCondition", subCondition.build()); + } + } + + public class PropertyCondition extends ComparisonCondition { + + PropertyCondition(String conditionTypeId, String propertyName, DefinitionsService definitionsService) { + super(conditionTypeId, definitionsService); + condition.setParameter("propertyName", propertyName); + } + + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/ConditionESQueryBuilderTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ConditionESQueryBuilderTest.java b/itests/src/test/java/org/apache/unomi/itests/ConditionESQueryBuilderTest.java new file mode 100644 index 0000000..82e1780 --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/ConditionESQueryBuilderTest.java @@ -0,0 +1,59 @@ +/* + * 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.unomi.api.Item; +import org.apache.unomi.api.conditions.Condition; +import org.junit.After; +import org.junit.Before; +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 java.util.List; + +/** + * Integration tests for various condition query builder types (elasticsearch). + * + * @author Sergiy Shyrkov + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerSuite.class) +public class ConditionESQueryBuilderTest extends ConditionEvaluatorTest { + + @Override + protected boolean eval(Condition c) { + @SuppressWarnings("unchecked") + List<Item> list = persistenceService.query(c,null,(Class<Item>) item.getClass()); + return list.contains(item); + } + + @Before + public void setUp() { + super.setUp(); + persistenceService.save(item); + persistenceService.refresh(); + } + + @After + public void tearDown() { + persistenceService.remove(item.getItemId(), item.getClass()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/ConditionEvaluatorTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ConditionEvaluatorTest.java b/itests/src/test/java/org/apache/unomi/itests/ConditionEvaluatorTest.java new file mode 100644 index 0000000..42301cc --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/ConditionEvaluatorTest.java @@ -0,0 +1,178 @@ +/* + * 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.unomi.api.Item; +import org.apache.unomi.api.Profile; +import org.apache.unomi.api.conditions.Condition; +import org.apache.unomi.api.services.DefinitionsService; +import org.apache.unomi.persistence.spi.PersistenceService; +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 javax.inject.Inject; +import java.util.*; + +import static org.junit.Assert.*; + +/** + * Integration tests for various condition types. + * + * @author Sergiy Shyrkov + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerSuite.class) +public class ConditionEvaluatorTest extends BaseTest { + + protected ConditionBuilder builder; + @Inject + protected PersistenceService persistenceService; + protected Item item; + protected Date lastVisit; + @Inject + private DefinitionsService definitionsService; + + protected boolean eval(Condition c) { + return persistenceService.testMatch(c, item); + } + + @Before + public void setUp() { + assertNotNull("Definition service should be available", definitionsService); + assertNotNull("Persistence service should be available", persistenceService); + + lastVisit = new GregorianCalendar(2015,1,1,20,30,0).getTime(); + + Profile profile = new Profile("profile-" + UUID.randomUUID().toString()); + profile.setProperty("firstVisit", lastVisit); + profile.setProperty("age", Integer.valueOf(30)); + profile.setProperty("gender", "female"); + profile.setProperty("lastVisit", lastVisit); + profile.setSegments(new HashSet<String>(Arrays.asList("s1", "s2", "s3"))); + this.item = profile; + builder = new ConditionBuilder(definitionsService); + } + + @Test + public void testCompound() { + // test AND + assertTrue(eval(builder.and(builder.profileProperty("properties.gender").equalTo("female"), + builder.profileProperty("properties.age").equalTo(Integer.valueOf(30))).build())); + assertFalse(eval(builder.and(builder.profileProperty("properties.gender").equalTo("male"), + builder.profileProperty("properties.age").equalTo(Integer.valueOf(30))).build())); + assertFalse(eval(builder.and(builder.profileProperty("properties.gender").equalTo("female"), + builder.profileProperty("properties.age").equalTo(Integer.valueOf(40))).build())); + + // test OR + assertTrue(eval(builder.or(builder.profileProperty("properties.gender").equalTo("female"), + builder.profileProperty("properties.age").equalTo(Integer.valueOf(40))).build())); + assertTrue(eval(builder.or(builder.profileProperty("properties.gender").equalTo("male"), + builder.profileProperty("properties.age").equalTo(Integer.valueOf(30))).build())); + assertFalse(eval(builder.or(builder.profileProperty("properties.gender").equalTo("male"), + builder.profileProperty("properties.age").equalTo(Integer.valueOf(40))).build())); + + // test NOT + assertTrue(eval(builder.not(builder.profileProperty("properties.gender").equalTo("male")).build())); + assertFalse(eval(builder.not(builder.profileProperty("properties.age").equalTo(Integer.valueOf(30))).build())); + + } + + @Test + public void testDate() { + assertTrue(eval(builder.profileProperty("properties.lastVisit").equalTo(lastVisit).build())); + assertTrue(eval(builder.profileProperty("properties.lastVisit") + .greaterThan(new Date(lastVisit.getTime() - 10000)).build())); + assertTrue(eval(builder.profileProperty("properties.lastVisit").lessThan(new Date(lastVisit.getTime() + 10000)) + .build())); + assertTrue(eval(builder.profileProperty("properties.lastVisit") + .in(new Date(lastVisit.getTime() + 10000), new Date(lastVisit.getTime() - 10000), lastVisit).build())); + assertTrue(eval(builder.profileProperty("properties.lastVisit") + .notIn(new Date(lastVisit.getTime() + 10000), new Date(lastVisit.getTime() - 10000)).build())); + assertFalse(eval(builder.profileProperty("properties.lastVisit") + .notIn(new Date(lastVisit.getTime() + 10000), new Date(lastVisit.getTime() - 10000), lastVisit).build())); + assertTrue(eval(builder.profileProperty("properties.lastVisit").all(lastVisit).build())); + assertFalse(eval(builder.profileProperty("properties.lastVisit") + .all(new Date(lastVisit.getTime() + 10000), lastVisit).build())); + } + + @Test + public void testExistence() { + assertTrue("Gender property does not exist", + eval(builder.profileProperty("properties.gender").exists().build())); + assertFalse("Gender property missing", eval(builder.profileProperty("properties.gender").missing().build())); + assertTrue("Strange property exists", eval(builder.profileProperty("properties.unknown").missing().build())); + assertFalse("Strange property exists", eval(builder.profileProperty("properties.unknown").exists().build())); + } + + @Test + public void testInteger() { + assertTrue(eval(builder.profileProperty("properties.age").equalTo(Integer.valueOf(30)).build())); + assertTrue(eval(builder.not(builder.profileProperty("properties.age").equalTo(Integer.valueOf(40))).build())); + assertTrue(eval(builder.profileProperty("properties.age").notEqualTo(Integer.valueOf(40)).build())); + assertTrue(eval(builder.profileProperty("properties.age").lessThan(Integer.valueOf(40)).build())); + assertTrue(eval(builder.profileProperty("properties.age").greaterThan(Integer.valueOf(20)).build())); + assertTrue(eval(builder.profileProperty("properties.age").greaterThanOrEqualTo(Integer.valueOf(30)).build())); + assertFalse(eval(builder.profileProperty("properties.age").greaterThanOrEqualTo(Integer.valueOf(31)).build())); + + assertTrue(eval(builder.profileProperty("properties.age").in(Integer.valueOf(30)).build())); + assertTrue(eval(builder.profileProperty("properties.age").in(Integer.valueOf(31), Integer.valueOf(30)).build())); + assertTrue(eval(builder.profileProperty("properties.age").notIn(Integer.valueOf(25), Integer.valueOf(26)) + .build())); + assertFalse(eval(builder.profileProperty("properties.age").notIn(Integer.valueOf(25), Integer.valueOf(30)) + .build())); + } + + @Test + public void testMultiValue() { + assertTrue(eval(builder.property("profileSegmentCondition", "segments").parameter("matchType", "in") + .parameter("segments", "s10", "s20", "s2").build())); + assertFalse(eval(builder.property("profileSegmentCondition", "segments").parameter("matchType", "in") + .parameter("segments", "s10", "s20", "s30").build())); + assertTrue(eval(builder.property("profileSegmentCondition", "segments").parameter("matchType", "notIn") + .parameter("segments", "s10", "s20", "s30").build())); + assertFalse(eval(builder.property("profileSegmentCondition", "segments").parameter("matchType", "notIn") + .parameter("segments", "s10", "s20", "s2").build())); + assertTrue(eval(builder.property("profileSegmentCondition", "segments").parameter("matchType", "all") + .parameter("segments", "s1", "s2").build())); + assertFalse(eval(builder.property("profileSegmentCondition", "segments").parameter("matchType", "all") + .parameter("segments", "s1", "s5").build())); + } + + @Test + public void testString() { + assertTrue(eval(builder.profileProperty("properties.gender").equalTo("female").build())); + assertFalse(eval(builder.not(builder.profileProperty("properties.gender").equalTo("female")).build())); + assertTrue(eval(builder.profileProperty("properties.gender").notEqualTo("male").build())); +// assertFalse(eval(builder.not(builder.profileProperty("properties.gender").notEqualTo("male")).build())); + assertTrue(eval(builder.profileProperty("properties.gender").startsWith("fe").build())); + assertTrue(eval(builder.profileProperty("properties.gender").endsWith("le").build())); + assertTrue(eval(builder.profileProperty("properties.gender").contains("fem").build())); + assertFalse(eval(builder.profileProperty("properties.gender").contains("mu").build())); + assertTrue(eval(builder.profileProperty("properties.gender").matchesRegex(".*ale").build())); + + assertTrue(eval(builder.profileProperty("properties.gender").in("male", "female").build())); + assertTrue(eval(builder.profileProperty("properties.gender").notIn("one", "two").build())); + assertFalse(eval(builder.profileProperty("properties.gender").notIn("one", "two", "female").build())); + assertTrue(eval(builder.profileProperty("properties.gender").all("female").build())); + assertFalse(eval(builder.profileProperty("properties.gender").all("male", "female").build())); + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/SegmentTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/SegmentTest.java b/itests/src/test/java/org/apache/unomi/itests/SegmentTest.java new file mode 100644 index 0000000..8f71f3f --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/SegmentTest.java @@ -0,0 +1,48 @@ +/* + * 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.unomi.api.Metadata; +import org.apache.unomi.api.services.SegmentService; +import org.junit.Assert; +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 javax.inject.Inject; +import java.util.List; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerSuite.class) +public class SegmentTest extends BaseTest{ + private final static Logger LOGGER = LoggerFactory.getLogger(SegmentTest.class); + @Inject + protected SegmentService segmentService; + + @Test + public void testSegments() { + Assert.assertNotNull("Segment service should be available", segmentService); + List<Metadata> segmentMetadatas = segmentService.getSegmentMetadatas(0, 50, null).getList(); + Assert.assertNotEquals("Segment metadata list should not be empty", 0, segmentMetadatas.size()); + LOGGER.info("Retrieved " + segmentMetadatas.size() + " segment metadata entries"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/apache/unomi/itests/TestUtils.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/TestUtils.java b/itests/src/test/java/org/apache/unomi/itests/TestUtils.java new file mode 100644 index 0000000..72f2d98 --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/TestUtils.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package org.apache.unomi.itests; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; + +public class TestUtils { + public static <T> T retrieveResourceFromResponse(HttpResponse response, Class<T> clazz) + throws IOException { + String jsonFromResponse = EntityUtils.toString(response.getEntity()); + ObjectMapper mapper = new ObjectMapper(). + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper.readValue(jsonFromResponse, clazz); + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/oasis_open/contextserver/itests/AllTests.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/oasis_open/contextserver/itests/AllTests.java b/itests/src/test/java/org/oasis_open/contextserver/itests/AllTests.java deleted file mode 100644 index 58aba41..0000000 --- a/itests/src/test/java/org/oasis_open/contextserver/itests/AllTests.java +++ /dev/null @@ -1,37 +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.oasis_open.contextserver.itests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -/** - * Defines suite of test classes to run. - * - * @author Sergiy Shyrkov - */ -@RunWith(Suite.class) -@SuiteClasses({ - //BasicTest.class, - ConditionEvaluatorTest.class, - ConditionESQueryBuilderTest.class, - SegmentTest.class - }) -public class AllTests { -} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/oasis_open/contextserver/itests/BaseTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/oasis_open/contextserver/itests/BaseTest.java b/itests/src/test/java/org/oasis_open/contextserver/itests/BaseTest.java deleted file mode 100644 index af603fc..0000000 --- a/itests/src/test/java/org/oasis_open/contextserver/itests/BaseTest.java +++ /dev/null @@ -1,100 +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.oasis_open.contextserver.itests; - -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; -import org.ops4j.pax.exam.options.MavenArtifactUrlReference; -import org.ops4j.pax.exam.options.MavenUrlReference; - -import java.io.File; - -import static org.ops4j.pax.exam.CoreOptions.*; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*; - -/** - * Base class for integration tests. - * - * @author kevan - */ -public abstract class BaseTest { - - protected static final String HTTP_PORT = "8181"; - - protected static final String URL = "http://localhost:" + HTTP_PORT; - - @Configuration - public Option[] config() { - MavenArtifactUrlReference karafUrl = maven() - .groupId("org.apache.karaf") - .artifactId("apache-karaf") - .version("3.0.2") - .type("tar.gz"); - - MavenUrlReference karafStandardRepo = maven() - .groupId("org.apache.karaf.features") - .artifactId("standard") - .classifier("features") - .type("xml") - .versionAsInProject(); - MavenUrlReference karafPaxWebRepo = maven() - .groupId("org.ops4j.pax.web") - .artifactId("pax-web-features") - .classifier("features") - .type("xml") - .versionAsInProject(); - MavenUrlReference karafCxfRepo = maven() - .groupId("org.apache.cxf.karaf") - .artifactId("apache-cxf") - .classifier("features") - .type("xml") - .versionAsInProject(); - MavenUrlReference contextServerRepo = maven() - .groupId("org.apache.unomi") - .artifactId("unomi-kar") - .classifier("features") - .type("xml") - .versionAsInProject(); - - return new Option[]{ - debugConfiguration("5005", false), - karafDistributionConfiguration() - .frameworkUrl(karafUrl) - .unpackDirectory(new File("target/exam")) - .useDeployFolder(false), -// keepRuntimeFolder(), - configureConsole().ignoreLocalConsole().ignoreRemoteShell(), - logLevel(LogLevel.INFO), -// editConfigurationFilePut("etc/org.ops4j.pax.web.cfg", "org.osgi.service.http.port", HTTP_PORT), -// systemProperty("org.osgi.service.http.port").value(HTTP_PORT), - features(karafPaxWebRepo, "war"), - features(karafCxfRepo, "cxf"), - features(karafStandardRepo, "openwebbeans"), - features(karafStandardRepo, "pax-cdi-web-openwebbeans"), - features(contextServerRepo, "unomi-kar"), - // we need to wrap the HttpComponents libraries ourselves since the OSGi bundles provided by the project are incorrect - wrappedBundle(mavenBundle("org.apache.httpcomponents", - "httpcore").versionAsInProject()), - wrappedBundle(mavenBundle("org.apache.httpcomponents", - "httpmime").versionAsInProject()), - wrappedBundle(mavenBundle("org.apache.httpcomponents", - "httpclient").versionAsInProject()) - }; - } -} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/oasis_open/contextserver/itests/BasicTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/oasis_open/contextserver/itests/BasicTest.java b/itests/src/test/java/org/oasis_open/contextserver/itests/BasicTest.java deleted file mode 100644 index 01113b7..0000000 --- a/itests/src/test/java/org/oasis_open/contextserver/itests/BasicTest.java +++ /dev/null @@ -1,99 +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.oasis_open.contextserver.itests; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.util.EntityUtils; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.oasis_open.contextserver.api.ContextRequest; -import org.oasis_open.contextserver.api.ContextResponse; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerSuite; -import java.io.IOException; - -@RunWith(PaxExam.class) -@ExamReactorStrategy(PerSuite.class) -public class BasicTest extends BaseTest{ - private static final String JSON_MYME_TYPE = "application/json"; - - private ObjectMapper objectMapper = new ObjectMapper(); - - @Test - public void testContextJS() throws IOException { - HttpUriRequest request = new HttpGet(URL + "/context.js?sessionId=aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d9"); - CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request); - // The underlying HTTP connection is still held by the response object - // to allow the response content to be streamed directly from the network socket. - // In order to ensure correct deallocation of system resources - // the profile MUST call CloseableHttpResponse#close() from a finally clause. - // Please note that if response content is not fully consumed the underlying - // connection cannot be safely re-used and will be shut down and discarded - // by the connection manager. - String responseContent = null; - try { - System.out.println(response.getStatusLine()); - HttpEntity entity = response.getEntity(); - // do something useful with the response body - // and ensure it is fully consumed - responseContent = EntityUtils.toString(entity); - } finally { - response.close(); - } - Assert.assertTrue("Response should contain context object", responseContent.contains("window.digitalData = window.digitalData || {};")); - // @todo we should check the validity of the context object, but this is rather complex since it would - // potentially require parsing the Javascript ! - } - - @Test - public void testContextJSON() throws IOException { - String sessionId = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d9"; - ContextRequest contextRequest = new ContextRequest(); -// contextRequest.setSource(new EventSource()); -// contextRequest.getSource().setId("af6f393a-a537-4586-991b-8521b9c7b05b"); - HttpPost request = new HttpPost(URL + "/context.json?sessionId=" + sessionId); - request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.create("application/json"))); - CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request); - - try { - // validate mimeType - String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType(); - Assert.assertEquals("Response content type should be " + JSON_MYME_TYPE, JSON_MYME_TYPE, mimeType); - - // validate context - ContextResponse context = TestUtils.retrieveResourceFromResponse(response, ContextResponse.class); - Assert.assertNotNull("Context should not be null", context); - Assert.assertNotNull("Context profileId should not be null", context.getProfileId()); - Assert.assertEquals("Context sessionId should be the same as the sessionId used to request the context", sessionId, context.getSessionId()); - } finally { - response.close(); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/itests/src/test/java/org/oasis_open/contextserver/itests/ConditionBuilder.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/oasis_open/contextserver/itests/ConditionBuilder.java b/itests/src/test/java/org/oasis_open/contextserver/itests/ConditionBuilder.java deleted file mode 100644 index 5794d84..0000000 --- a/itests/src/test/java/org/oasis_open/contextserver/itests/ConditionBuilder.java +++ /dev/null @@ -1,290 +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.oasis_open.contextserver.itests; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import org.oasis_open.contextserver.api.conditions.Condition; -import org.oasis_open.contextserver.api.services.DefinitionsService; - -/** - * Utility class for building conditions - * - * @author Sergiy Shyrkov - */ -public class ConditionBuilder { - - public abstract class ComparisonCondition extends ConditionItem { - - ComparisonCondition(String conditionTypeId, DefinitionsService definitionsService) { - super(conditionTypeId, definitionsService); - } - - public ComparisonCondition all(String... values) { - return op("all").stringValues(values); - } - - public ComparisonCondition all(Date... values) { - return op("all").dateValues(values); - } - - public ComparisonCondition all(Integer... values) { - return op("all").integerValues(values); - } - - public ComparisonCondition contains(String value) { - return op("contains").stringValue(value); - } - - public ComparisonCondition endsWith(String value) { - return op("endsWith").stringValue(value); - } - - public ComparisonCondition equalTo(String value) { - return op("equals").stringValue(value); - } - - public ComparisonCondition equalTo(Date value) { - return op("equals").dateValue(value); - } - - public ComparisonCondition equalTo(Integer value) { - return op("equals").integerValue(value); - } - - public ComparisonCondition exists() { - return op("exists"); - } - - public ComparisonCondition greaterThan(Date value) { - return op("greaterThan").dateValue(value); - } - - public ComparisonCondition greaterThan(Integer value) { - return op("greaterThan").integerValue(value); - } - - public ComparisonCondition greaterThanOrEqualTo(Date value) { - return op("greaterThanOrEqualTo").dateValue(value); - } - - public ComparisonCondition greaterThanOrEqualTo(Integer value) { - return op("greaterThanOrEqualTo").integerValue(value); - } - - public ComparisonCondition in(String... values) { - return op("in").stringValues(values); - } - - public ComparisonCondition in(Date... values) { - return op("in").dateValues(values); - } - - public ComparisonCondition in(Integer... values) { - return op("in").integerValues(values); - } - - public ComparisonCondition lessThan(Date value) { - return op("lessThan").dateValue(value); - } - - public ComparisonCondition lessThan(Integer value) { - return op("lessThan").integerValue(value); - } - - public ComparisonCondition lessThanOrEqualTo(Date value) { - return op("lessThanOrEqualTo").dateValue(value); - } - - public ComparisonCondition lessThanOrEqualTo(Integer value) { - return op("lessThanOrEqualTo").integerValue(value); - } - - public ComparisonCondition between(Date lowerBound, Date upperBound) { - return op("between").dateValues(lowerBound, upperBound); - } - - public ComparisonCondition between(Integer lowerBound, Integer upperBound) { - return op("between").integerValues(lowerBound, upperBound); - } - - public ComparisonCondition matchesRegex(String value) { - return op("matchesRegex").stringValue(value); - } - - public ComparisonCondition missing() { - return op("missing"); - } - - public ComparisonCondition notEqualTo(String value) { - return op("notEquals").stringValue(value); - } - - public ComparisonCondition notEqualTo(Date value) { - return op("notEquals").dateValue(value); - } - - public ComparisonCondition notEqualTo(Integer value) { - return op("notEquals").integerValue(value); - } - - public ComparisonCondition notIn(String... values) { - return op("notIn").stringValues(values); - } - - public ComparisonCondition notIn(Date... values) { - return op("notIn").dateValues(values); - } - - public ComparisonCondition notIn(Integer... values) { - return op("notIn").integerValues(values); - } - - private ComparisonCondition op(String op) { - return parameter("comparisonOperator", op); - } - - @Override - public ComparisonCondition parameter(String name, Object value) { - return (ComparisonCondition) super.parameter(name, value); - } - - public ComparisonCondition parameter(String name, Object... values) { - return (ComparisonCondition) super.parameter(name, values); - } - - public ComparisonCondition startsWith(String value) { - return op("startsWith").stringValue(value); - } - - private ComparisonCondition stringValue(String value) { - return parameter("propertyValue", value); - } - - private ComparisonCondition integerValue(Integer value) { - return parameter("propertyValueInteger", value); - } - - private ComparisonCondition dateValue(Date value) { - return parameter("propertyValueDate", value); - } - - private ComparisonCondition stringValues(String... values) { - return parameter("propertyValues", values != null ? Arrays.asList(values) : null); - } - - private ComparisonCondition integerValues(Integer... values) { - return parameter("propertyValuesInteger", values != null ? Arrays.asList(values) : null); - } - - private ComparisonCondition dateValues(Date... values) { - return parameter("propertyValuesDate", values != null ? Arrays.asList(values) : null); - } - } - - public class CompoundCondition extends ConditionItem { - - CompoundCondition(ConditionItem condition1, ConditionItem condition2, String operator) { - super("booleanCondition", condition1.definitionsService); - parameter("operator", operator); - ArrayList<Condition> subConditions = new ArrayList<Condition>(2); - subConditions.add(condition1.build()); - subConditions.add(condition2.build()); - parameter("subConditions", subConditions); - } - } - - public abstract class ConditionItem { - - protected Condition condition; - - private DefinitionsService definitionsService; - - ConditionItem(String conditionTypeId, DefinitionsService definitionsService) { - this.definitionsService = definitionsService; - condition = new org.oasis_open.contextserver.api.conditions.Condition( - this.definitionsService.getConditionType(conditionTypeId)); - } - - public Condition build() { - return condition; - } - - public ConditionItem parameter(String name, Object value) { - condition.setParameter(name, value); - return this; - } - - public ConditionItem parameter(String name, Object... values) { - condition.setParameter(name, values != null ? Arrays.asList(values) : null); - return this; - } - - } - - public class NotCondition extends ConditionItem { - - NotCondition(ConditionItem subCondition) { - super("notCondition", subCondition.definitionsService); - parameter("subCondition", subCondition.build()); - } - } - - public class PropertyCondition extends ComparisonCondition { - - PropertyCondition(String conditionTypeId, String propertyName, DefinitionsService definitionsService) { - super(conditionTypeId, definitionsService); - condition.setParameter("propertyName", propertyName); - } - - } - - private DefinitionsService definitionsService; - - /** - * Initializes an instance of this class. - * - * @param definitionsService - * an instance of the {@link DefinitionsService} - */ - public ConditionBuilder(DefinitionsService definitionsService) { - super(); - this.definitionsService = definitionsService; - } - - public CompoundCondition and(ConditionItem condition1, ConditionItem condition2) { - return new CompoundCondition(condition1, condition2, "and"); - } - - public NotCondition not(ConditionItem subCondition) { - return new NotCondition(subCondition); - } - - public CompoundCondition or(ConditionItem condition1, ConditionItem condition2) { - return new CompoundCondition(condition1, condition2, "or"); - } - - public PropertyCondition profileProperty(String propertyName) { - return new PropertyCondition("profilePropertyCondition", propertyName, definitionsService); - } - - public PropertyCondition property(String conditionTypeId, String propertyName) { - return new PropertyCondition(conditionTypeId, propertyName, definitionsService); - } -}
