This is an automated email from the ASF dual-hosted git repository. asi pushed a commit to branch Unomi-487-backup in repository https://gitbox.apache.org/repos/asf/unomi.git
commit ce36a4c27f51e6a7887cff548f008e304c46cb43 Author: Anatol Sialitski <[email protected]> AuthorDate: Thu Feb 17 18:16:35 2022 +0300 UNOMI-487 Add profile alias management to REST API and GraphQL API --- .../apache/unomi/api/services/ProfileService.java | 4 + .../graphql/commands/AddAliasToProfileCommand.java | 66 +++++++++++++ .../commands/RemoveAliasFromProfileCommand.java | 69 ++++++++++++++ .../factories/ProfileAliasConditionFactory.java | 77 +++++++++++++++ .../FindProfileAliasConnectionDataFetcher.java | 71 ++++++++++++++ .../profile/GetProfileAliasesDataFetcher.java | 47 ++++++++++ .../fetchers/profile/ProfileAliasDataFetcher.java | 41 ++++++++ .../types/input/CDPProfileAliasFilterInput.java | 83 ++++++++++++++++ .../graphql/types/input/CDPProfileAliasInput.java | 53 +++++++++++ .../unomi/graphql/types/output/CDPMutation.java | 27 ++++++ .../graphql/types/output/CDPProfileAlias.java | 66 +++++++++++++ .../types/output/CDPProfileAliasConnection.java | 66 +++++++++++++ .../graphql/types/output/CDPProfileAliasEdge.java | 49 ++++++++++ .../unomi/graphql/types/output/CDPQuery.java | 36 ++++++- .../org/apache/unomi/itests/ProfileServiceIT.java | 17 +++- .../itests/graphql/GraphQLProfileAliasesIT.java | 104 +++++++++++++++++++++ .../graphql/profileAlias/addAliasToProfile.json | 16 ++++ .../graphql/profileAlias/findProfileAliases.json | 8 ++ .../graphql/profileAlias/getProfileAlias.json | 5 + .../graphql/profileAlias/getProfileAliases.json | 5 + .../profileAlias/removeAliasFromProfile.json | 13 +++ .../rest/endpoints/ProfileServiceEndPoint.java | 27 ++++++ .../services/impl/profiles/ProfileServiceImpl.java | 45 +++++++++ 23 files changed, 989 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/org/apache/unomi/api/services/ProfileService.java b/api/src/main/java/org/apache/unomi/api/services/ProfileService.java index b2698c424..2f03e5246 100644 --- a/api/src/main/java/org/apache/unomi/api/services/ProfileService.java +++ b/api/src/main/java/org/apache/unomi/api/services/ProfileService.java @@ -110,6 +110,10 @@ public interface ProfileService { void addAliasToProfile(String profileID, String alias, String clientID); + ProfileAlias removeAliasFromProfile(String profileID, String alias, String clientID); + + PartialList<ProfileAlias> findProfileAliases(String profileId, int offset, int size, String sortBy); + /** * Merge the specified profile properties in an existing profile,or save new profile if it does not exist yet * diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/commands/AddAliasToProfileCommand.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/commands/AddAliasToProfileCommand.java new file mode 100644 index 000000000..4ba18d570 --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/commands/AddAliasToProfileCommand.java @@ -0,0 +1,66 @@ +/* + * 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.graphql.commands; + +import org.apache.unomi.api.ProfileAlias; +import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.graphql.types.input.CDPProfileAliasInput; +import org.apache.unomi.graphql.types.output.CDPProfileAlias; +import org.apache.unomi.persistence.spi.PersistenceService; + +public class AddAliasToProfileCommand extends BaseCommand<CDPProfileAlias> { + + private final CDPProfileAliasInput profileAliasInput; + + public AddAliasToProfileCommand(Builder builder) { + super(builder); + this.profileAliasInput = builder.profileAliasInput; + } + + @Override + public CDPProfileAlias execute() { + ProfileService profileService = serviceManager.getService(ProfileService.class); + + profileService.addAliasToProfile( + profileAliasInput.getProfileID().getId(), + profileAliasInput.getAlias(), + profileAliasInput.getProfileID().getClient().getId()); + + PersistenceService persistenceService = serviceManager.getService(PersistenceService.class); + persistenceService.refreshIndex(ProfileAlias.class, null); + + return new CDPProfileAlias(persistenceService.load(profileAliasInput.getAlias(), ProfileAlias.class)); + } + + public static Builder create() { + return new Builder(); + } + + public static class Builder extends BaseCommand.Builder<Builder> { + + private CDPProfileAliasInput profileAliasInput; + + public Builder profileAliasInput(CDPProfileAliasInput profileAliasInput) { + this.profileAliasInput = profileAliasInput; + return this; + } + + public AddAliasToProfileCommand build() { + return new AddAliasToProfileCommand(this); + } + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/commands/RemoveAliasFromProfileCommand.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/commands/RemoveAliasFromProfileCommand.java new file mode 100644 index 000000000..63aa06529 --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/commands/RemoveAliasFromProfileCommand.java @@ -0,0 +1,69 @@ +/* + * 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.graphql.commands; + +import org.apache.unomi.api.ProfileAlias; +import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.graphql.types.input.CDPProfileIDInput; +import org.apache.unomi.graphql.types.output.CDPProfileAlias; + +public class RemoveAliasFromProfileCommand extends BaseCommand<CDPProfileAlias> { + + private final String alias; + + private final CDPProfileIDInput profileIDInput; + + private RemoveAliasFromProfileCommand(Builder builder) { + super(builder); + this.alias = builder.alias; + this.profileIDInput = builder.profileIDInput; + } + + @Override + public CDPProfileAlias execute() { + ProfileService profileService = serviceManager.getService(ProfileService.class); + + ProfileAlias profileAlias = profileService.removeAliasFromProfile(profileIDInput.getId(), alias, profileIDInput.getClient().getId()); + + return profileAlias != null ? new CDPProfileAlias(profileAlias) : null; + } + + public static Builder create() { + return new Builder(); + } + + public static class Builder extends BaseCommand.Builder<Builder> { + + private String alias; + + private CDPProfileIDInput profileIDInput; + + public Builder setAlias(String alias) { + this.alias = alias; + return this; + } + + public Builder setProfileIDInput(CDPProfileIDInput profileIDInput) { + this.profileIDInput = profileIDInput; + return this; + } + + public RemoveAliasFromProfileCommand build() { + return new RemoveAliasFromProfileCommand(this); + } + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileAliasConditionFactory.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileAliasConditionFactory.java new file mode 100644 index 000000000..28c6340aa --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileAliasConditionFactory.java @@ -0,0 +1,77 @@ +/* + * 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.graphql.condition.factories; + +import graphql.schema.DataFetchingEnvironment; +import org.apache.unomi.api.conditions.Condition; +import org.apache.unomi.graphql.types.input.CDPProfileAliasFilterInput; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ProfileAliasConditionFactory extends ConditionFactory { + + private static ProfileAliasConditionFactory instance; + + public static synchronized ProfileAliasConditionFactory get(final DataFetchingEnvironment environment) { + if (instance == null) { + instance = new ProfileAliasConditionFactory(environment); + } + + return instance; + } + + private ProfileAliasConditionFactory(final DataFetchingEnvironment environment) { + super("profileAliasesPropertyCondition", environment); + } + + @SuppressWarnings("unchecked") + public Condition filterInputCondition(final CDPProfileAliasFilterInput filterInput, final Map<String, Object> filterInputAsMap) { + if (filterInput == null) { + return matchAllCondition(); + } + + final List<Condition> rootSubConditions = new ArrayList<>(); + + if (filterInput.getAlias_equals() != null) { + rootSubConditions.add(propertyCondition("itemId", filterInput.getAlias_equals())); + } + + if (filterInput.getProfileID_equals() != null) { + rootSubConditions.add(propertyCondition("profileID.keyword", filterInput.getProfileID_equals())); + } + + if (filterInput.getClientID_equals() != null) { + rootSubConditions.add(propertyCondition("clientID.keyword", filterInput.getClientID_equals())); + } + + if (filterInputAsMap.get("and") != null) { + final List<Map<String, Object>> andFilterInputAsMap = (List<Map<String, Object>>) filterInputAsMap.get("and"); + + rootSubConditions.add(filtersToCondition(filterInput.getAnd(), andFilterInputAsMap, this::filterInputCondition, "and")); + } + + if (filterInputAsMap.get("or") != null) { + final List<Map<String, Object>> orFilterInputAsMap = (List<Map<String, Object>>) filterInputAsMap.get("or"); + + rootSubConditions.add(filtersToCondition(filterInput.getOr(), orFilterInputAsMap, this::filterInputCondition, "or")); + } + + return booleanCondition("and", rootSubConditions); + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfileAliasConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfileAliasConnectionDataFetcher.java new file mode 100644 index 000000000..e6dea6006 --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfileAliasConnectionDataFetcher.java @@ -0,0 +1,71 @@ +/* + * 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.graphql.fetchers.profile; + +import graphql.schema.DataFetchingEnvironment; +import org.apache.unomi.api.PartialList; +import org.apache.unomi.api.ProfileAlias; +import org.apache.unomi.api.conditions.Condition; +import org.apache.unomi.api.query.Query; +import org.apache.unomi.graphql.condition.factories.ProfileAliasConditionFactory; +import org.apache.unomi.graphql.fetchers.BaseConnectionDataFetcher; +import org.apache.unomi.graphql.fetchers.ConnectionParams; +import org.apache.unomi.graphql.services.ServiceManager; +import org.apache.unomi.graphql.types.input.CDPOrderByInput; +import org.apache.unomi.graphql.types.input.CDPProfileAliasFilterInput; +import org.apache.unomi.graphql.types.output.CDPPageInfo; +import org.apache.unomi.graphql.types.output.CDPProfileAliasConnection; +import org.apache.unomi.graphql.types.output.CDPProfileAliasEdge; +import org.apache.unomi.persistence.spi.PersistenceService; + +import java.util.List; +import java.util.stream.Collectors; + +public class FindProfileAliasConnectionDataFetcher extends BaseConnectionDataFetcher<CDPProfileAliasConnection> { + + private final CDPProfileAliasFilterInput filterInput; + + private final List<CDPOrderByInput> orderByInput; + + public FindProfileAliasConnectionDataFetcher( + final CDPProfileAliasFilterInput filterInput, final List<CDPOrderByInput> orderByInput) { + this.filterInput = filterInput; + this.orderByInput = orderByInput; + } + + @Override + public CDPProfileAliasConnection get(DataFetchingEnvironment environment) throws Exception { + final ServiceManager serviceManager = environment.getContext(); + + final PersistenceService persistenceService = serviceManager.getService(PersistenceService.class); + + final ConnectionParams params = parseConnectionParams(environment); + + final Query query = buildQuery(createCondition(environment), orderByInput, params); + + final PartialList<ProfileAlias> partialList = persistenceService.query( + query.getCondition(), query.getSortby(), ProfileAlias.class, query.getOffset(), query.getLimit()); + + final List<CDPProfileAliasEdge> edges = partialList.getList().stream().map(CDPProfileAliasEdge::new).collect(Collectors.toList()); + + return new CDPProfileAliasConnection(edges, new CDPPageInfo(), partialList.getTotalSize()); + } + + private Condition createCondition(final DataFetchingEnvironment environment) { + return ProfileAliasConditionFactory.get(environment).filterInputCondition(filterInput, environment.getArgument("filter")); + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/GetProfileAliasesDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/GetProfileAliasesDataFetcher.java new file mode 100644 index 000000000..0b14d3d33 --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/GetProfileAliasesDataFetcher.java @@ -0,0 +1,47 @@ +/* + * 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.graphql.fetchers.profile; + +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import org.apache.unomi.api.PartialList; +import org.apache.unomi.api.ProfileAlias; +import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.graphql.services.ServiceManager; +import org.apache.unomi.graphql.types.output.CDPProfileAlias; + +import java.util.List; +import java.util.stream.Collectors; + +public class GetProfileAliasesDataFetcher implements DataFetcher<List<CDPProfileAlias>> { + + private final String profileId; + + public GetProfileAliasesDataFetcher(final String profileId) { + this.profileId = profileId; + } + + @Override + public List<CDPProfileAlias> get(final DataFetchingEnvironment environment) throws Exception { + ServiceManager serviceManager = environment.getContext(); + + ProfileService profileService = serviceManager.getService(ProfileService.class); + PartialList<ProfileAlias> partialList = profileService.findProfileAliases(profileId, 0, 100, null); + + return partialList.getList().stream().map(CDPProfileAlias::new).collect(Collectors.toList()); + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAliasDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAliasDataFetcher.java new file mode 100644 index 000000000..fd99e06e6 --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAliasDataFetcher.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.unomi.graphql.fetchers.profile; + +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import org.apache.unomi.api.ProfileAlias; +import org.apache.unomi.graphql.services.ServiceManager; +import org.apache.unomi.graphql.types.output.CDPProfileAlias; +import org.apache.unomi.persistence.spi.PersistenceService; + +public class ProfileAliasDataFetcher implements DataFetcher<CDPProfileAlias> { + + private final String alias; + + public ProfileAliasDataFetcher(final String alias) { + this.alias = alias; + } + + @Override + public CDPProfileAlias get(final DataFetchingEnvironment environment) throws Exception { + ServiceManager serviceManager = environment.getContext(); + PersistenceService persistenceService = serviceManager.getService(PersistenceService.class); + ProfileAlias profileAlias = persistenceService.load(alias, ProfileAlias.class); + return profileAlias != null ? new CDPProfileAlias(profileAlias) : null; + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/input/CDPProfileAliasFilterInput.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/input/CDPProfileAliasFilterInput.java new file mode 100644 index 000000000..ace68007a --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/input/CDPProfileAliasFilterInput.java @@ -0,0 +1,83 @@ +/* + * 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.graphql.types.input; + +import graphql.annotations.annotationTypes.GraphQLField; +import graphql.annotations.annotationTypes.GraphQLName; + +import java.util.List; + +import static org.apache.unomi.graphql.types.input.CDPProfileAliasFilterInput.TYPE_NAME; + +@GraphQLName(TYPE_NAME) +public class CDPProfileAliasFilterInput { + + public static final String TYPE_NAME = "CDP_ProfileAliasFilterInput"; + + @GraphQLField + @GraphQLName("and") + private final List<CDPProfileAliasFilterInput> and; + + @GraphQLField + @GraphQLName("or") + private final List<CDPProfileAliasFilterInput> or; + + @GraphQLField + @GraphQLName("alias_equals") + private final String alias_equals; + + @GraphQLField + @GraphQLName("profileID_equals") + private final String profileID_equals; + + @GraphQLField + @GraphQLName("clientID_equals") + private final String clientID_equals; + + public CDPProfileAliasFilterInput( + @GraphQLName("and") List<CDPProfileAliasFilterInput> and, + @GraphQLName("or") List<CDPProfileAliasFilterInput> or, + @GraphQLName("alias_equals") String alias_equals, + @GraphQLName("profileID_equals") String profileID_equals, + @GraphQLName("clientID_equals") String clientID_equals) { + this.and = and; + this.or = or; + this.alias_equals = alias_equals; + this.profileID_equals = profileID_equals; + this.clientID_equals = clientID_equals; + } + + public List<CDPProfileAliasFilterInput> getAnd() { + return and; + } + + public List<CDPProfileAliasFilterInput> getOr() { + return or; + } + + public String getAlias_equals() { + return alias_equals; + } + + public String getProfileID_equals() { + return profileID_equals; + } + + public String getClientID_equals() { + return clientID_equals; + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/input/CDPProfileAliasInput.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/input/CDPProfileAliasInput.java new file mode 100644 index 000000000..1351a8cce --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/input/CDPProfileAliasInput.java @@ -0,0 +1,53 @@ +/* + * 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.graphql.types.input; + +import graphql.annotations.annotationTypes.GraphQLField; +import graphql.annotations.annotationTypes.GraphQLID; +import graphql.annotations.annotationTypes.GraphQLName; +import graphql.annotations.annotationTypes.GraphQLNonNull; + +import static org.apache.unomi.graphql.types.input.CDPProfileAliasInput.TYPE_NAME; + +@GraphQLName(TYPE_NAME) +public class CDPProfileAliasInput { + + public static final String TYPE_NAME = "CDP_ProfileAliasInput"; + + @GraphQLID + @GraphQLField + @GraphQLNonNull + private final String alias; + + @GraphQLField + @GraphQLNonNull + private final CDPProfileIDInput profileID; + + public CDPProfileAliasInput(@GraphQLID @GraphQLNonNull @GraphQLName("alias") String alias, + @GraphQLNonNull @GraphQLName("profileID") CDPProfileIDInput profileID) { + this.alias = alias; + this.profileID = profileID; + } + + public String getAlias() { + return alias; + } + + public CDPProfileIDInput getProfileID() { + return profileID; + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPMutation.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPMutation.java index ee1cdeb49..26f88bdd1 100644 --- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPMutation.java +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPMutation.java @@ -21,6 +21,7 @@ import graphql.annotations.annotationTypes.GraphQLID; import graphql.annotations.annotationTypes.GraphQLName; import graphql.annotations.annotationTypes.GraphQLNonNull; import graphql.schema.DataFetchingEnvironment; +import org.apache.unomi.graphql.commands.AddAliasToProfileCommand; import org.apache.unomi.graphql.commands.CreateOrUpdatePersonaCommand; import org.apache.unomi.graphql.commands.CreateOrUpdateProfilePropertiesCommand; import org.apache.unomi.graphql.commands.CreateOrUpdateSourceCommand; @@ -33,6 +34,7 @@ import org.apache.unomi.graphql.commands.DeleteSourceCommand; import org.apache.unomi.graphql.commands.DeleteTopicCommand; import org.apache.unomi.graphql.commands.DeleteViewCommand; import org.apache.unomi.graphql.commands.ProcessEventsCommand; +import org.apache.unomi.graphql.commands.RemoveAliasFromProfileCommand; import org.apache.unomi.graphql.commands.list.AddProfileToListCommand; import org.apache.unomi.graphql.commands.list.CreateOrUpdateListCommand; import org.apache.unomi.graphql.commands.list.DeleteListCommand; @@ -43,6 +45,7 @@ import org.apache.unomi.graphql.commands.segments.DeleteSegmentCommand; import org.apache.unomi.graphql.types.input.CDPEventInput; import org.apache.unomi.graphql.types.input.CDPListInput; import org.apache.unomi.graphql.types.input.CDPPersonaInput; +import org.apache.unomi.graphql.types.input.CDPProfileAliasInput; import org.apache.unomi.graphql.types.input.CDPProfileIDInput; import org.apache.unomi.graphql.types.input.CDPPropertyInput; import org.apache.unomi.graphql.types.input.CDPSegmentInput; @@ -265,4 +268,28 @@ public class CDPMutation { .execute(); } + @GraphQLField + public CDPProfileAlias addAliasToProfile( + final @GraphQLNonNull @GraphQLName("profileAlias") CDPProfileAliasInput profileAliasInput, + final DataFetchingEnvironment environment) { + return AddAliasToProfileCommand.create() + .profileAliasInput(profileAliasInput) + .setEnvironment(environment) + .build() + .execute(); + } + + @GraphQLField + public CDPProfileAlias removeAliasFromProfile( + final @GraphQLID @GraphQLNonNull @GraphQLName("alias") String alias, + final @GraphQLName("profileID") CDPProfileIDInput profileIDInput, + final DataFetchingEnvironment environment + ) { + return RemoveAliasFromProfileCommand.create() + .setAlias(alias) + .setProfileIDInput(profileIDInput) + .setEnvironment(environment) + .build() + .execute(); + } } diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAlias.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAlias.java new file mode 100644 index 000000000..cf2b3bbfa --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAlias.java @@ -0,0 +1,66 @@ +/* + * 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.graphql.types.output; + +import graphql.annotations.annotationTypes.GraphQLDescription; +import graphql.annotations.annotationTypes.GraphQLField; +import graphql.annotations.annotationTypes.GraphQLName; +import org.apache.unomi.api.ProfileAlias; + +import java.time.OffsetDateTime; +import java.time.ZoneId; + +import static org.apache.unomi.graphql.types.output.CDPProfileAlias.TYPE_NAME; + +@GraphQLName(TYPE_NAME) +@GraphQLDescription("Alias for Profile.") +public class CDPProfileAlias { + public static final String TYPE_NAME = "CDP_ProfileAlias"; + + private final ProfileAlias profileAlias; + + public CDPProfileAlias(final ProfileAlias profileAlias) { + this.profileAlias = profileAlias; + } + + @GraphQLField + public String alias() { + return profileAlias != null ? profileAlias.getItemId() : null; + } + + @GraphQLField + public CDPProfileID profileID() { + if (profileAlias != null) { + CDPProfileID profileID = new CDPProfileID(profileAlias.getProfileID()); + if (profileAlias.getClientID() != null) { + profileID.setClient(new CDPClient(profileAlias.getClientID(), profileAlias.getClientID())); + } + return profileID; + } + return null; + } + + @GraphQLField + public OffsetDateTime creationTime() { + return profileAlias != null ? profileAlias.getCreationTime().toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime() : null; + } + + @GraphQLField + public OffsetDateTime modifiedTime() { + return profileAlias != null ? profileAlias.getModifiedTime().toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime() : null; + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAliasConnection.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAliasConnection.java new file mode 100644 index 000000000..a6a9459b1 --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAliasConnection.java @@ -0,0 +1,66 @@ +/* + * 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.graphql.types.output; + +import graphql.annotations.annotationTypes.GraphQLField; +import graphql.annotations.annotationTypes.GraphQLName; + +import java.util.ArrayList; +import java.util.List; + +import static org.apache.unomi.graphql.types.output.CDPProfileAliasConnection.TYPE_NAME; + +@GraphQLName(TYPE_NAME) +public class CDPProfileAliasConnection { + + public static final String TYPE_NAME = "CDP_ProfileAliasConnection"; + + private final List<CDPProfileAliasEdge> edges; + + private final CDPPageInfo pageInfo; + + private final Long totalCount; + + public CDPProfileAliasConnection() { + this(new ArrayList<>(), new CDPPageInfo(), 0L); + } + + public CDPProfileAliasConnection( + final List<CDPProfileAliasEdge> edges, final CDPPageInfo pageInfo, final Long totalCount) { + this.edges = edges; + this.pageInfo = pageInfo; + this.totalCount = totalCount; + } + + @GraphQLField + @GraphQLName("edges") + public List<CDPProfileAliasEdge> edges() { + return edges; + } + + @GraphQLField + @GraphQLName("pageInfo") + public CDPPageInfo pageInfo() { + return pageInfo; + } + + @GraphQLField + @GraphQLName("totalCount") + public Long totalCount() { + return totalCount; + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAliasEdge.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAliasEdge.java new file mode 100644 index 000000000..293b7678f --- /dev/null +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPProfileAliasEdge.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.unomi.graphql.types.output; + +import graphql.annotations.annotationTypes.GraphQLField; +import graphql.annotations.annotationTypes.GraphQLName; +import graphql.annotations.annotationTypes.GraphQLNonNull; +import graphql.schema.DataFetchingEnvironment; +import org.apache.unomi.api.ProfileAlias; + +import static org.apache.unomi.graphql.types.output.CDPProfileAliasEdge.TYPE_NAME; + +@GraphQLName(TYPE_NAME) +public class CDPProfileAliasEdge { + + public static final String TYPE_NAME = "CDP_ProfileAliasEdge"; + + private final ProfileAlias profileAlias; + + public CDPProfileAliasEdge(final ProfileAlias profileAlias) { + this.profileAlias = profileAlias; + } + + @GraphQLField + @GraphQLName("node") + public CDPProfileAlias node(final DataFetchingEnvironment environment) { + return new CDPProfileAlias(profileAlias); + } + + @GraphQLNonNull + @GraphQLField + public String cursor() { + return profileAlias != null ? profileAlias.getItemId() : null; + } +} diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java index e723fcf17..2b7ba0d1e 100644 --- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java +++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java @@ -16,7 +16,11 @@ */ package org.apache.unomi.graphql.types.output; -import graphql.annotations.annotationTypes.*; +import graphql.annotations.annotationTypes.GraphQLDescription; +import graphql.annotations.annotationTypes.GraphQLField; +import graphql.annotations.annotationTypes.GraphQLID; +import graphql.annotations.annotationTypes.GraphQLName; +import graphql.annotations.annotationTypes.GraphQLNonNull; import graphql.schema.DataFetchingEnvironment; import org.apache.unomi.graphql.fetchers.FindTopicsConnectionDataFetcher; import org.apache.unomi.graphql.fetchers.SourceDataFetcher; @@ -26,7 +30,10 @@ import org.apache.unomi.graphql.fetchers.event.EventDataFetcher; import org.apache.unomi.graphql.fetchers.event.FindEventsConnectionDataFetcher; import org.apache.unomi.graphql.fetchers.list.GetListDataFetcher; import org.apache.unomi.graphql.fetchers.list.ListConnectionDataFetcher; +import org.apache.unomi.graphql.fetchers.profile.FindProfileAliasConnectionDataFetcher; import org.apache.unomi.graphql.fetchers.profile.FindProfilesConnectionDataFetcher; +import org.apache.unomi.graphql.fetchers.profile.GetProfileAliasesDataFetcher; +import org.apache.unomi.graphql.fetchers.profile.ProfileAliasDataFetcher; import org.apache.unomi.graphql.fetchers.profile.ProfileDataFetcher; import org.apache.unomi.graphql.fetchers.profile.PropertiesConnectionDataFetcher; import org.apache.unomi.graphql.fetchers.segment.FindSegmentsConnectionDataFetcher; @@ -35,6 +42,7 @@ import org.apache.unomi.graphql.fetchers.segment.UnomiSegmentDataFetcher; import org.apache.unomi.graphql.types.input.CDPEventFilterInput; import org.apache.unomi.graphql.types.input.CDPListFilterInput; import org.apache.unomi.graphql.types.input.CDPOrderByInput; +import org.apache.unomi.graphql.types.input.CDPProfileAliasFilterInput; import org.apache.unomi.graphql.types.input.CDPProfileFilterInput; import org.apache.unomi.graphql.types.input.CDPProfileIDInput; import org.apache.unomi.graphql.types.input.CDPSegmentFilterInput; @@ -174,4 +182,30 @@ public class CDPQuery { return new ListConnectionDataFetcher(filterInput, orderByInput).get(environment); } + @GraphQLField + public CDPProfileAlias getProfileAlias( + final @GraphQLID @GraphQLNonNull @GraphQLName("alias") String alias, + final DataFetchingEnvironment environment) throws Exception { + return new ProfileAliasDataFetcher(alias).get(environment); + } + + @GraphQLField + public List<CDPProfileAlias> getProfileAliases( + final @GraphQLID @GraphQLName("profileID") @GraphQLNonNull String profileID, + final DataFetchingEnvironment environment) throws Exception { + return new GetProfileAliasesDataFetcher(profileID).get(environment); + } + + @GraphQLField + public CDPProfileAliasConnection findProfileAliases( + final @GraphQLName("filter") CDPProfileAliasFilterInput filterInput, + final @GraphQLName("orderBy") List<CDPOrderByInput> orderByInput, + final @GraphQLName("first") Integer first, + final @GraphQLName("after") String after, + final @GraphQLName("last") Integer last, + final @GraphQLName("before") String before, + final DataFetchingEnvironment environment + ) throws Exception { + return new FindProfileAliasConnectionDataFetcher(filterInput, orderByInput).get(environment); + } } diff --git a/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java b/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java index e9bf22105..b91aec295 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java @@ -29,6 +29,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; + +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.Before; @@ -44,6 +46,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import java.util.stream.IntStream; import javax.inject.Inject; @@ -179,7 +182,8 @@ public class ProfileServiceIT extends BaseIT { @Test public void testLoadProfileByAlias() throws Exception { - String profileID = "profileID_testLoadProfileByAlias"; + String profileID = UUID.randomUUID().toString(); + try { Profile profile = new Profile(); profile.setItemId(profileID); @@ -189,7 +193,7 @@ public class ProfileServiceIT extends BaseIT { IntStream.range(1, 3).forEach(index -> { final String profileAlias = profileID + "_alias_" + index; - profileService.addAliasToProfile(profileID, profileAlias, "clientID"); + profileService.addAliasToProfile(profileID, profileAlias, "clientID" + index); }); refreshPersistence(); @@ -205,13 +209,16 @@ public class ProfileServiceIT extends BaseIT { storedProfile = profileService.load(profileID + "_alias_2"); assertNotNull(storedProfile); assertEquals(profileID, storedProfile.getItemId()); - } finally { - profileService.delete(profileID, false); + PartialList<ProfileAlias> aliasList = profileService.findProfileAliases(profileID, 0, 10, null); + assertEquals(2, aliasList.size()); + } finally { IntStream.range(1, 3).forEach(index -> { final String profileAlias = profileID + "_alias_" + index; - persistenceService.remove(profileAlias, ProfileAlias.class); + profileService.removeAliasFromProfile(profileID, profileAlias, "clientID" + index); }); + + profileService.delete(profileID, false); } } diff --git a/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLProfileAliasesIT.java b/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLProfileAliasesIT.java new file mode 100644 index 000000000..6cd62759e --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLProfileAliasesIT.java @@ -0,0 +1,104 @@ +/* + * 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.graphql; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.unomi.api.Profile; +import org.apache.unomi.api.ProfileAlias; +import org.apache.unomi.api.services.ProfileService; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.ops4j.pax.exam.util.Filter; + +import javax.inject.Inject; + +public class GraphQLProfileAliasesIT extends BaseGraphQLIT { + + @Inject + @Filter(timeout = 600000) + protected ProfileService profileService; + + @Before + public void setUp() throws InterruptedException { + removeItems(ProfileAlias.class); + removeItems(Profile.class); + } + + @Test + public void lifecycle() throws Exception { + final Profile profile = new Profile("f6c1c5a0-eff3-42b7-b375-44da5d01f2a6"); + profileService.save(profile); + + // test adding an alias to a profile + try (CloseableHttpResponse response = post("graphql/profileAlias/addAliasToProfile.json")) { + final ResponseContext context = ResponseContext.parse(response.getEntity()); + + Assert.assertNotNull(context.getValue("data.cdp.addAliasToProfile")); + Assert.assertEquals("myAlias", context.getValue("data.cdp.addAliasToProfile.alias")); + Assert.assertNotNull(context.getValue("data.cdp.addAliasToProfile.profileID")); + Assert.assertEquals("f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + context.getValue("data.cdp.addAliasToProfile.profileID.id")); + Assert.assertNotNull(context.getValue("data.cdp.addAliasToProfile.profileID.client")); + Assert.assertEquals("facebook", context.getValue("data.cdp.addAliasToProfile.profileID.client.ID")); + } + + // test fetching a profile by an alias + try (CloseableHttpResponse response = post("graphql/profileAlias/getProfileAlias.json")) { + final ResponseContext context = ResponseContext.parse(response.getEntity()); + + Assert.assertNotNull(context.getValue("data.cdp.getProfileAlias")); + Assert.assertEquals("myAlias", context.getValue("data.cdp.getProfileAlias.alias")); + Assert.assertNotNull(context.getValue("data.cdp.getProfileAlias.profileID")); + Assert.assertEquals("f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + context.getValue("data.cdp.getProfileAlias.profileID.id")); + } + + // test fetching a profile's aliases + try (CloseableHttpResponse response = post("graphql/profileAlias/getProfileAliases.json")) { + final ResponseContext context = ResponseContext.parse(response.getEntity()); + + Assert.assertNotNull(context.getValue("data.cdp.getProfileAliases")); + Assert.assertEquals("myAlias", context.getValue("data.cdp.getProfileAliases[0].alias")); + Assert.assertNotNull(context.getValue("data.cdp.getProfileAliases[0].profileID")); + Assert.assertEquals("f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + context.getValue("data.cdp.getProfileAliases[0].profileID.id")); + } + + // test filtering a profile aliases by criteria + try (CloseableHttpResponse response = post("graphql/profileAlias/findProfileAliases.json")) { + final ResponseContext context = ResponseContext.parse(response.getEntity()); + + Assert.assertNotNull(context.getValue("data.cdp.findProfileAliases")); + Assert.assertEquals("myAlias", context.getValue("data.cdp.findProfileAliases.edges[0].node.alias")); + Assert.assertNotNull(context.getValue("data.cdp.findProfileAliases.edges[0].node.profileID")); + Assert.assertEquals("f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + context.getValue("data.cdp.findProfileAliases.edges[0].node.profileID.id")); + } + + // test removing an alias from a profile + try (CloseableHttpResponse response = post("graphql/profileAlias/removeAliasFromProfile.json")) { + final ResponseContext context = ResponseContext.parse(response.getEntity()); + + Assert.assertNotNull(context.getValue("data.cdp.removeAliasFromProfile")); + Assert.assertEquals("myAlias", context.getValue("data.cdp.removeAliasFromProfile.alias")); + Assert.assertNotNull(context.getValue("data.cdp.removeAliasFromProfile.profileID")); + Assert.assertEquals("f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + context.getValue("data.cdp.removeAliasFromProfile.profileID.id")); + } + } +} diff --git a/itests/src/test/resources/graphql/profileAlias/addAliasToProfile.json b/itests/src/test/resources/graphql/profileAlias/addAliasToProfile.json new file mode 100644 index 000000000..81a2f7e0a --- /dev/null +++ b/itests/src/test/resources/graphql/profileAlias/addAliasToProfile.json @@ -0,0 +1,16 @@ +{ + "operationName": "addAliasToProfile", + "variables": { + "profileAlias": { + "alias": "myAlias", + "profileID": { + "id": "f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + "client": { + "id": "facebook", + "title": "Facebook" + } + } + } + }, + "query": "mutation addAliasToProfile($profileAlias: CDP_ProfileAliasInput!) {\n cdp {\n addAliasToProfile(profileAlias: $profileAlias) {\n alias\n profileID {\n client {\n ID\n title\n }\n id\n }\n }\n }\n}\n" +} diff --git a/itests/src/test/resources/graphql/profileAlias/findProfileAliases.json b/itests/src/test/resources/graphql/profileAlias/findProfileAliases.json new file mode 100644 index 000000000..5e4abddc6 --- /dev/null +++ b/itests/src/test/resources/graphql/profileAlias/findProfileAliases.json @@ -0,0 +1,8 @@ +{ + "operationName": null, + "variables": { + "alias": "myAlias", + "clientID": "facebook" + }, + "query": "query ($alias: String, $clientID: String) {\n cdp {\n findProfileAliases(filter: {and: [{alias_equals: $alias}, {clientID_equals: $clientID}]}) {\n totalCount\n edges {\n cursor\n node {\n alias\n profileID {\n id\n client {\n ID\n }\n }\n }\n }\n }\n }\n}\n" +} diff --git a/itests/src/test/resources/graphql/profileAlias/getProfileAlias.json b/itests/src/test/resources/graphql/profileAlias/getProfileAlias.json new file mode 100644 index 000000000..8c972904d --- /dev/null +++ b/itests/src/test/resources/graphql/profileAlias/getProfileAlias.json @@ -0,0 +1,5 @@ +{ + "operationName": null, + "variables": {}, + "query": "{\n cdp {\n getProfileAlias(alias: \"myAlias\") {\n alias\n creationTime\n modifiedTime\n profileID {\n id\n }\n }\n }\n}\n" +} diff --git a/itests/src/test/resources/graphql/profileAlias/getProfileAliases.json b/itests/src/test/resources/graphql/profileAlias/getProfileAliases.json new file mode 100644 index 000000000..32f4a7885 --- /dev/null +++ b/itests/src/test/resources/graphql/profileAlias/getProfileAliases.json @@ -0,0 +1,5 @@ +{ + "operationName": null, + "variables": {}, + "query": "{\n cdp {\n getProfileAliases(profileID: \"f6c1c5a0-eff3-42b7-b375-44da5d01f2a6\") {\n alias\n creationTime\n modifiedTime\n profileID {\n client {\n ID\n title\n }\n id\n }\n }\n }\n}\n" +} diff --git a/itests/src/test/resources/graphql/profileAlias/removeAliasFromProfile.json b/itests/src/test/resources/graphql/profileAlias/removeAliasFromProfile.json new file mode 100644 index 000000000..915dba2c6 --- /dev/null +++ b/itests/src/test/resources/graphql/profileAlias/removeAliasFromProfile.json @@ -0,0 +1,13 @@ +{ + "operationName": "removeAliasFromProfile", + "variables": { + "alias": "myAlias", + "profileID": { + "id": "f6c1c5a0-eff3-42b7-b375-44da5d01f2a6", + "client": { + "id": "facebook" + } + } + }, + "query": "mutation removeAliasFromProfile($alias: ID!, $profileID: CDP_ProfileIDInput!) {\n cdp {\n removeAliasFromProfile(alias: $alias, profileID: $profileID) {\n alias\n creationTime\n modifiedTime\n profileID {\n id\n client {\n ID\n title\n }\n }\n }\n }\n}\n" +} diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java index db6aa93db..86b50b714 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java @@ -622,4 +622,31 @@ public class ProfileServiceEndPoint { public PartialList<Session> searchSession(Query query) { return profileService.searchSessions(query); } + + @POST + @Path("/{profileId}/aliases/{aliasId}") + public void addAliasToProfile(final @PathParam("profileId") String profileId, + final @PathParam("aliasId") String aliasId, + final @HeaderParam("X-Unomi-ClientId") String headerClientID) { + String clientId = headerClientID != null ? headerClientID : "defaultClientId"; + profileService.addAliasToProfile(profileId, aliasId, clientId); + } + + @DELETE + @Path("/{profileId}/aliases/{aliasId}") + public void removeAliasFromProfile(final @PathParam("profileId") String profileId, + final @PathParam("aliasId") String aliasId, + final @HeaderParam("X-Unomi-ClientId") String headerClientID) { + String clientId = headerClientID != null ? headerClientID : "defaultClientId"; + profileService.removeAliasFromProfile(profileId, aliasId, clientId); + } + + @GET + @Path("/{profileId}/aliases") + public PartialList<ProfileAlias> listAliasesByProfileId(final @PathParam("profileId") String profileId, + @QueryParam("offset") @DefaultValue("0") int offset, + @QueryParam("size") @DefaultValue("50") int size, + @QueryParam("sort") String sortBy) { + return profileService.findProfileAliases(profileId, offset, size, sortBy); + } } diff --git a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java index 148a98d96..4903074af 100644 --- a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java @@ -581,6 +581,51 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } } + @Override + public ProfileAlias removeAliasFromProfile(String profileID, String alias, String clientID) { + Condition profileIDCondition = new Condition(definitionsService.getConditionType("profileAliasesPropertyCondition")); + profileIDCondition.setParameter("propertyName", "profileID.keyword"); + profileIDCondition.setParameter("comparisonOperator", "equals"); + profileIDCondition.setParameter("propertyValue", profileID); + + Condition clientIDCondition = new Condition(definitionsService.getConditionType("profileAliasesPropertyCondition")); + clientIDCondition.setParameter("propertyName", "clientID.keyword"); + clientIDCondition.setParameter("comparisonOperator", "equals"); + clientIDCondition.setParameter("propertyValue", clientID); + + Condition aliasCondition = new Condition(definitionsService.getConditionType("profileAliasesPropertyCondition")); + aliasCondition.setParameter("propertyName", "itemId"); + aliasCondition.setParameter("comparisonOperator", "equals"); + aliasCondition.setParameter("propertyValue", alias); + + List<Condition> conditions = new ArrayList<>(); + conditions.add(profileIDCondition); + conditions.add(clientIDCondition); + conditions.add(aliasCondition); + + Condition condition = new Condition(definitionsService.getConditionType("booleanCondition")); + condition.setParameter("operator", "and"); + condition.setParameter("subConditions", conditions); + + List<ProfileAlias> profileAliases = persistenceService.query(condition, null, ProfileAlias.class); + + if (profileAliases.size() == 1 && persistenceService.removeByQuery(condition, ProfileAlias.class)) { + return profileAliases.get(0); + } + + return null; + } + + @Override + public PartialList<ProfileAlias> findProfileAliases(String profileId, int offset, int size, String sortBy) { + Condition condition = new Condition(definitionsService.getConditionType("profileAliasesPropertyCondition")); + condition.setParameter("propertyName", "profileID.keyword"); + condition.setParameter("comparisonOperator", "equals"); + condition.setParameter("propertyValue", profileId); + + return persistenceService.query(condition, sortBy, ProfileAlias.class, offset, size); + } + private Profile save(Profile profile, boolean forceRefresh) { if (profile.getItemId() == null) { return null;
